2013-07-10 40 views
6

Questa è un'estensione del mio question.Pandas Dataframe suddiviso in sessioni

Per semplificare Si supponga di avere un dataframe panda come segue.

df = pd.DataFrame([[1.1, 1.1, 2.5, 2.6, 2.5, 3.4,2.6,2.6,3.4], list('AAABBBBAB'), [1.1, 1.7, 2.5, 2.6, 3.3, 3.8,4.0,4.2,4.3]]).T 
df.columns = ['col1', 'col2','col3'] 

dataframe:

col1 col2 col3 
0 1.1 A 1.1 
1 1.1 A 1.7 
2 2.5 A 2.5 
3 2.6 B 2.6 
4 2.5 B 3.3 
5 3.4 B 3.8 
6 2.6 B 4 
7 2.6 A 4.2 
8 3.4 B 4.3 

voglio gruppo presente sulla base di alcune condizioni. La logica si basa su valori col2 col1 e la differenza cumulativa di col3:

  1. Vai a col1 e trovare altre occorrenze dello stesso valore.
  2. Nel mio caso il primo valore di col1 è '1.1' e anche in questo caso il loro valore è uguale a row2.
  3. quindi controllare il valore col2, se sono simili, quindi ottenere la differenza cumulativa di Col 3.
  4. Se la differenza cumulativa è superiore a 0,5 allora contrassegnare questo come una nuova sessione.
  5. Se i valori col1 sono gli stessi, ma i valori col2 sono diversi quindi contrassegnarli come nuova sessione

risultato atteso:

col1 col2 col3 session 
0 1.1 A 1.1 0 
1 1.1 A 1.7 1 
2 2.5 A 2.5 2 
3 2.6 B 2.6 4 
4 2.5 B 3.3 3 
5 3.4 B 3.8 7 
6 2.6 B 4 5 
7 2.6 A 4.2 6 
8 3.4 B 4.3 7 
+0

@unutbu:!! dovrebbe essere .. :) Grazie –

risposta

6

Come nella risposta eccellente si è collegato al;) prima di creare il numero di sessione :

In [11]: g = df.groupby(['col1', 'col2']) 

In [12]: df['session_number'] = g['col3'].apply(lambda s: (s - s.shift(1) > 0.5).fillna(0).cumsum(skipna=False)) 

allora penso che si desidera set_index di queste colonne, questo può essere sufficiente per molti casi d'uso (anche se potrebbe essere la pena di fare un 01.238.378,174176 millions):

In [13]: df1 = df.set_index(['col1', 'col2', 'session_number']) 

In [14]: df1 
Out[14]: 
         col3 
col1 col2 session_number 
1.1 A 0    1.1 
      1    1.7 
2.5 A 0    2.5 
2.6 B 0    2.6 
2.5 B 0    3.3 
3.4 B 0    3.8 
2.6 B 1     4 
    A 0    4.2 
3.4 B 0    4.3 

Se davvero si vuole si può afferrare il numero di sessione:

In [15]: g1 = df.groupby(['col1', 'col2', 'session_number']) # I think there is a slightly neater way, but I forget.. 

In [16]: df1['session'] = g1.apply(lambda x: 1).cumsum() # could -1 here if it matters 

In [17]: df1 
Out[17]: 
         col3 session 
col1 col2 session_number 
1.1 A 0    1.1  1 
      1    1.7  2 
2.5 A 0    2.5  3 
2.6 B 0    2.6  6 
2.5 B 0    3.3  4 
3.4 B 0    3.8  8 
2.6 B 1     4  7 
    A 0    4.2  5 
3.4 B 0    4.3  8 

Se si desidera che questo in colonne (come nella tua domanda) il reset_index e si potrebbe eliminare la colonna della sessione :

In [18]: df1.reset_index() 
Out[18]: 
    col1 col2 session_number col3 session 
0 1.1 A    0 1.1  1 
1 1.1 A    1 1.7  2 
2 2.5 A    0 2.5  3 
3 2.6 B    0 2.6  6 
4 2.5 B    0 3.3  4 
5 3.4 B    0 3.8  8 
6 2.6 B    1 4  7 
7 2.6 A    0 4.2  5 
8 3.4 B    0 4.3  8 
+0

Again..Superb ed eccellente ... non ho parole per spiegare :) –