2017-10-10 1 views
3

Der beste Weg, um zu erklären, was ich versuche zu erreichen, ist wahrscheinlich nur ein Beispiel. Gegeben die folgenden dataFrame:Abschnitt ein Pandas Datenframe in 'Chunks' basierend auf Spaltenwert

 tag ID 
0  0 1 
1  0 2 
2  1 3 
3  1 4 
4  0 5 
5  1 6 
6  0 7 
7  0 8 
8  1 9 
9  1 10 
10 0 11 
11 0 12 
12 0 13 
13 1 14 
14 1 15 
15 1 16 
16 0 17 

Basierend auf dem Tag, Abschnitt der DataFrame in "Chunks". Wenn ein Chunk identifiziert wird, wird er in einem separaten dataFrame (oder einer Liste von dataFrames?) Gespeichert. Das Kriterium für "Chunking" wäre, in der Tag-Spalte nach 2 oder mehr Nullen zu suchen. Wenn mehr als 2 Nullen vorhanden sind, dann trennen Sie alle Daten zwischen den vorherigen Nullen und den aktuellen Nullen.

In meinem Beispiel Datenrahmen oben, würde der Code der Zeilen indiziert loszuwerden: 0,1,6,7,10,11,12 ... dann wäre es die folgenden Stücke in getrennte Datenrahmen speichern:

 tag ID 
2  1 3 
3  1 4 
4  0 5 
5  1 6 

    tag ID 
8  1 9 
9  1 10 

    tag ID 
13 1 14 
14 1 15 
15 1 16 
16 0 17 

Ich hoffe es ist klar. Entschuldigung, wenn nicht ... Gibt es einen guten pythonischen Weg, dies zu erreichen, ohne ein riesiges Durcheinander an Schleifen zu erzeugen?

Danke für die Hilfe, CJ

Antwort

2

Schon mein Bestes versuchen ... Ich bin mit zwei weiteren neuen Parameter

df['group']=df.tag.diff().fillna(0).ne(0).cumsum() 
df1=df.groupby('group').tag.agg([sum,lambda x : len(x)]) 
dropindex=df1[(df1['sum']==0)&(df1['<lambda>']>1)].index # only drop more than one continue 0 
df=df.loc[~df.group.isin(dropindex)] 
df['group2']=df.reset_index()['index'].diff().ne(1).cumsum().values 
for _, dfyourneed in df.groupby('group2',as_index=False): 
    print(dfyourneed.drop(['group2','group'],1)) 

    tag ID 
2 1 3 
3 1 4 
4 0 5 
5 1 6 
    tag ID 
8 1 9 
9 1 10 
    tag ID 
13 1 14 
14 1 15 
15 1 16 
16 0 17 

Oder Sie können es in die Liste speichern

[dfyourneed.drop(['group2', 'group'], 1) for _, dfyourneed in df.groupby('group2', as_index=False)] 
Out[1083]: 
[ tag ID 
2 1 3 
3 1 4 
4 0 5 
5 1 6, tag ID 
8 1 9 
9 1 10,  tag ID 
13 1 14 
14 1 15 
15 1 16 
16 0 17] 
+0

@ piRSquared, Das ist super nah! Das einzige Problem ist, dass wir die Reihen mit nur einer Null weggeworfen haben. Ich mag es, Zeile 4 in der ersten Gruppe und Zeile 16 in der Astgruppe zu behalten, weil sie nur eine Null haben. – cmj29607

+0

@ cmj29607 ok :-) lass uns auf seine antwort warten :-) – Wen

+0

@ Wen. kann nicht sagen, dass ich deine Antwort völlig verstehen kann ... dennoch muss ich analysieren, was du näher getan hast. Was ich bemerke, ist, dass dies leicht auf eine beliebige Anzahl von Nullen für die Definition eines Chunks verallgemeinert werden kann. df1 ['']> n). sehr nett :) ty! – cmj29607

1

Hier ist, was ich versucht habe, Create df_new durch Ausschließen von Zeilen mit zwei oder mehr Nullen.

df_new = df[(df.tag + df.tag.shift() != 0) & (df.tag + df.tag.shift(-1) != 0)] 

erstellen numpy Array der Indizes von df_new und es

auf Indizes
a = np.array(df_new.index.tolist()) 
l = np.split(a, np.where(np.diff(a) != 1)[0]+1) 

Erstellen Sie eine Liste von df mit Liste Verständnis

df_list = [df.iloc[i] for i in l] 

Für den Zugriff auf die auf kontinuierliche Werte spaltete basierend Datenrahmen, verwenden Sie

df_list[0] 

    tag ID 
2 1 3 
3 1 4 
4 0 5 
5 1 6 
+0

danken Ihnen! Ihre Antwort ist sehr kompakt :) Ich habe eine harte Zeit zu wissen, wie ich * .shift verwenden würde, um die Chunk-Kriterien zu verallgemeinern. Zum Beispiel, wenn die Chunk-Grenze durch eine große Anzahl von Nullen definiert werden soll ... – cmj29607

+0

Ja, aber das wäre sehr schnell :) Die aktuelle Lösung würde zwei oder mehr Nullen behandeln – Vaishali

Verwandte Themen