2013-07-10 13 views
6

Jest to rozszerzenie mojego question.Panda DataFame podzielona na sesje

Aby było to łatwiejsze Przyjmijmy, że mam pandasową ramkę danych w następujący sposób.

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 

Chcę grupa ta opiera się na pewnych warunkach. Logika oparta jest na wartościach col1 col2 i skumulowanej różnicy col3:

  1. Przejdź do col1 i znajdź inne wystąpienia tej samej wartości.
  2. W moim przypadku pierwsza wartość col1 to "1.1" i znowu ich wartość jest taka sama w wierszu 2.
  3. Następnie sprawdź wartość col2, jeśli są one podobne, a następnie uzyskaj skumulowaną różnicę kol. 3.
  4. Jeśli łączna różnica jest większa niż 0,5, oznacz to jako nową sesję.
  5. Jeśli wartości col1 są takie same, ale wartości col2 różnią następnie oznaczyć je jako nowej sesji

oczekiwany wynik:

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:! To powinno być .. :) –

Odpowiedz

6

jak w doskonałą odpowiedzią ty związanej;) najpierw utworzyć numer sesji :

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)) 

Wtedy myślę chcesz set_index z tych kolumn, może to być wystarczające dla wielu usecases (choć być może warto robić sort):

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 

Jeśli naprawdę chcesz, możesz chwycić się numer sesji:

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 

Jeśli chcesz to w kolumnach (tak jak w pytaniu) reset_index i można usunąć kolumnę sesji :

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

Thanks Again..Superb i doskonała ... nie mam słów, aby wyjaśnić :) –