bet*_*eta 10 python dataframe pandas
我有一个pandas数据帧如下:
time winner loser stat
1 A B 0
2 C B 0
3 D B 1
4 E B 0
5 F A 0
6 G A 0
7 H A 0
8 I A 1
Run Code Online (Sandbox Code Playgroud)
每一行都是匹配结果.第一列是匹配的时间,第二列和第三列包含赢家/输家,第四列是匹配的一个统计.
我想检测每个输家的统计数据为零.
预期结果应如下所示:
time winner loser stat streak
1 A B 0 1
2 C B 0 2
3 D B 1 0
4 E B 0 1
5 F A 0 1
6 G A 0 2
7 H A 0 3
8 I A 1 0
Run Code Online (Sandbox Code Playgroud)
在伪代码中,算法应该像这样工作:
.groupby loser 柱. loser组的每一行stat列:如果包含0,streak则从上一行增加值0.如果不是0,然后开始一个新的streak,那就是,把0入streak列.所以.groupby很清楚.但那时我需要某种.apply我可以看到前一行的地方?这是我被困的地方.
jez*_*ael 13
你可以apply自定义函数f,然后cumsum,cumcount和astype:
def f(x):
x['streak'] = x.groupby( (x['stat'] != 0).cumsum()).cumcount() +
( (x['stat'] != 0).cumsum() == 0).astype(int)
return x
df = df.groupby('loser', sort=False).apply(f)
print df
time winner loser stat streak
0 1 A B 0 1
1 2 C B 0 2
2 3 D B 1 0
3 4 E B 0 1
4 5 F A 0 1
5 6 G A 0 2
6 7 H A 0 3
7 8 I A 1 0
Run Code Online (Sandbox Code Playgroud)
为了更好的未成年:
def f(x):
x['c'] = (x['stat'] != 0).cumsum()
x['a'] = (x['c'] == 0).astype(int)
x['b'] = x.groupby( 'c' ).cumcount()
x['streak'] = x.groupby( 'c' ).cumcount() + x['a']
return x
df = df.groupby('loser', sort=False).apply(f)
print df
time winner loser stat c a b streak
0 1 A B 0 0 1 0 1
1 2 C B 0 0 1 1 2
2 3 D B 1 1 0 0 0
3 4 E B 0 1 0 1 1
4 5 F A 0 0 1 0 1
5 6 G A 0 0 1 1 2
6 7 H A 0 0 1 2 3
7 8 I A 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
不像 jezrael 的回答那么优雅,但对我来说更容易理解......
首先,定义一个适用于单个失败者的函数:
def f(df):
df['streak2'] = (df['stat'] == 0).cumsum()
df['cumsum'] = np.nan
df.loc[df['stat'] == 1, 'cumsum'] = df['streak2']
df['cumsum'] = df['cumsum'].fillna(method='ffill')
df['cumsum'] = df['cumsum'].fillna(0)
df['streak'] = df['streak2'] - df['cumsum']
df.drop(['streak2', 'cumsum'], axis=1, inplace=True)
return df
Run Code Online (Sandbox Code Playgroud)
连胜本质上是 a cumsum,但我们每次需要将其重置stat为 1。 因此我们减去cumsumwhere的值stat是 1,结转直到下一个 1。
然后groupby和apply失败者:
df.groupby('loser').apply(f)
Run Code Online (Sandbox Code Playgroud)
结果如预期。
| 归档时间: |
|
| 查看次数: |
1540 次 |
| 最近记录: |