2016-11-28 1 views
2

Ich habe einen pandas Datenrahmen in der folgenden Weise definiert:Python pandas Datenrahmen 1 nicht Null ist und nicht alle NaN Attribute n Zeilen

2009-11-18 500.0 
2009-11-19 500.0 
2009-11-20 NaN 
2009-11-23 500.0 
2009-11-24 500.0 
2009-11-25 NaN 
2009-11-27 NaN 
2009-11-30 NaN 
2009-12-01 500.0 
2009-12-02 500.0 
2009-12-03 500.0 
2009-12-04 500.0 
2009-12-07 NaN 
2009-12-08 NaN 
2009-12-09 500.0 
2009-12-10 500.0 
2009-12-11 500.0 
2009-12-14 500.0 

Meine Absicht ist es ein nicht NaN Element alle n Zeilen zu halten. Wenn zum Beispiel mein n 4 ist, würde ich 2009-11-18 500 behalten und alles andere auf (einschließlich) 2009-11-23 auf 0 setzen, würde ich dasselbe für andere Elemente des Arrays wiederholen, gibt es einen effizienten, pythonische, vektorisierte Art und Weise dies zu tun?

Um dieses zu konkretisieren, beabsichtige ich schließlich auf Array wie folgt aussehen:

2009-11-18 500.0 
2009-11-19 0 
2009-11-20 0 
2009-11-23 0 
2009-11-24 500.0 
2009-11-25 0 
2009-11-27 0 
2009-11-30 0 
2009-12-01 500.0 
2009-12-02 0 
2009-12-03 0 
2009-12-04 0 
2009-12-07 0 
2009-12-08 0 
2009-12-09 500.0 
2009-12-10 0 
2009-12-11 0 
2009-12-14 0 
+0

Also wenn die Länge der letzten Gruppe ist nicht '4', Wert weglassen? – jezrael

Antwort

1

Ich glaube, Sie erste np.arange mit Boden Divison für die Erstellung von Gruppen, groupby dann und erste nicht erhalten Index von NaN verwenden können Wert von idxmax. Letzte 0 von where erhalten, wenn keine Werte von a enthält:

print (np.arange(len(df.index)) // 4) 
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4] 

idx = df.col.groupby([np.arange(len(df.index)) // 4]).idxmin() 
print (idx) 
0 2009-11-18 
1 2009-11-24 
2 2009-12-01 
3 2009-12-09 
4 2009-12-11 
Name: col, dtype: datetime64[ns] 

df.col = df.col.where(df.index.isin(idx), 0) 
print (df) 
       col 
2009-11-18 500.0 
2009-11-19 0.0 
2009-11-20 0.0 
2009-11-23 0.0 
2009-11-24 500.0 
2009-11-25 0.0 
2009-11-27 0.0 
2009-11-30 0.0 
2009-12-01 500.0 
2009-12-02 0.0 
2009-12-03 0.0 
2009-12-04 0.0 
2009-12-07 0.0 
2009-12-08 0.0 
2009-12-09 500.0 
2009-12-10 0.0 
2009-12-11 500.0 
2009-12-14 0.0 

Lösung, wenn die Länge der letzten Gruppe ist nicht 4, letzten Wert Weglassung:

arr = np.arange(len(df.index)) // 4 
print (arr) 
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4] 

#if equal by last value of array substract 1 
arr1 = np.where(arr == arr[-1], arr[-1] - 1, arr) 
print (arr1) 
[0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 3 3] 

idx = df.col.groupby(arr1).idxmin() 
print (idx) 
0 2009-11-18 
1 2009-11-24 
2 2009-12-01 
3 2009-12-09 
Name: col, dtype: datetime64[ns] 
df.col = df.col.where(df.index.isin(idx), 0) 
print (df) 
       col 
2009-11-18 500.0 
2009-11-19 0.0 
2009-11-20 0.0 
2009-11-23 0.0 
2009-11-24 500.0 
2009-11-25 0.0 
2009-11-27 0.0 
2009-11-30 0.0 
2009-12-01 500.0 
2009-12-02 0.0 
2009-12-03 0.0 
2009-12-04 0.0 
2009-12-07 0.0 
2009-12-08 0.0 
2009-12-09 500.0 
2009-12-10 0.0 
2009-12-11 0.0 
2009-12-14 0.0 
1

IIUC
Sie Starten Sie Ihren Zähler neu, wenn Sie Ihren nächsten Wert erhalten. In diesem Fall würde ich einen Generator verwenden. Nicht vektorisiert!

def next4(s): 
    idx = s.first_valid_index() 
    while idx is not None: 
     loc = s.index.get_loc(idx) 
     yield s.loc[[idx]] 
     idx = s.iloc[loc+4:].first_valid_index() 

pd.concat(next4(df[1])).reindex(df.index, fill_value=0).to_frame() 

enter image description here

Verwandte Themen