簡體   English   中英

如何計算 pandas dataframe 中組內的列中連續值的數量?

[英]How can I calculate number of consecutive values in a column within a group in a pandas dataframe?

我有一個 dataframe 與所有戰斗機的戰斗,戰斗編號(即,如果它是他們的第一,第二等),以及他們是否贏得了戰斗。 我想計算一個戰士在他們當前的戰斗之前獲得的連續勝利次數(即不包括他們是否贏得了當前的戰斗)。 我目前正在 Spyder 中使用 Python 3.7。

假設我們有以下 dataframe,如果戰斗機贏得戰斗,則 win = 1:

df = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'], 
                  'fight_number' :  ['1', '2', '3', '4', '1', '2', '3', '1', '2'],
                  'win' : [0, 0, 1, 1, 1, 1, 0, 1, 1]})
  fighter  fight_number  win
0       A             1     0
1       A             2     0
2       A             3     1
3       A             4     1
4       B             1     1
5       B             2     1
6       B             3     0
7       C             1     1
8       C             2     1

我知道要計算所有行的連勝記錄,我可以實施此處提出的解決方案:

grouper = (df.win != df.win.shift()).cumsum()
df['streak'] = df.groupby(grouper).cumsum()

產生:

  fighter fight_number  win  streak
0       A            1    0       0
1       A            2    0       0
2       A            3    1       1
3       A            4    1       2
4       B            1    1       3
5       B            2    1       4
6       B            3    0       0
7       C            1    1       1
8       C            2    1       2

但是我需要將這種方法應用於 dataframe 的子組(即每個戰斗機),並且不將當前戰斗的結果包括在連續計數中。 所以,我基本上是想在他們進入戰斗時擁有戰士目前的連勝紀錄。

因此,此示例中的目標 output 將是:

  fighter fight_number  win  streak
0       A            1    0       0
1       A            2    0       0
2       A            3    1       0
3       A            4    1       1
4       B            1    1       0
5       B            2    1       1
6       B            3    0       2
7       C            1    1       0
8       C            2    1       1

我很感激我能得到的任何建議,因為我對 Python 還是很陌生。

我提出的一個解決方案受到jezrael發布(但已刪除)的早期答案的啟發:

grouper = (df.win != df.win.shift()).cumsum()
df['streak'] = df.groupby(['fighter', grouper]).cumsum()
df['streak'] = df.groupby('fighter')['streak'].shift(1).fillna(0)

生成目標 output:

  fighter fight_number  win  streak
0       A            1    0     0.0
1       A            2    0     0.0
2       A            3    1     0.0
3       A            4    1     1.0
4       B            1    1     0.0
5       B            2    1     1.0
6       B            3    0     2.0
7       C            1    1     0.0
8       C            2    1     1.0

它似乎也適用於其他測試示例:

df2 = pd.DataFrame({'fighter' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C'], 
                  'fight number' :  ["1", "2", "3", "4", "5", "6", "1", "2", "3", "1", "2"],
                  'win' : [1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]}) 

grouper = (df2.win != df2.win.shift()).cumsum()
df2['streak'] = df2.groupby(['fighter', grouper]).cumsum()
df2['streak'] = df2.groupby('fighter')['streak'].shift(1).fillna(0)

   fighter fight number  win  streak
0        A            1    1     0.0
1        A            2    1     1.0
2        A            3    0     2.0
3        A            4    1     0.0
4        A            5    0     1.0
5        A            6    1     0.0
6        B            1    1     0.0
7        B            2    1     1.0
8        B            3    0     2.0
9        C            1    1     0.0
10       C            2    1     1.0

df = df.groupby(['fighter','fight_number','win'])['win'].sum().groupby(['fighter']).cumsum().reset_index(name='streak')

出於某種原因,喬的回答不太奏效,但確實如此:

df = df.sort_values(['fighter', 'date'])
grouper = (df.win != df.win.shift()).cumsum()
df['streak'] = df.groupby(['fighter', grouper])['win'].cumsum()
df.sort_index(inplace=True)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM