有条件地对熊猫数据框使用cumcount

时间:2018-06-25 08:01:27

标签: python pandas dataframe group-by pandas-groupby

考虑数据框

df = pd.DataFrame(
    [
        ['A', 1],
        ['A', 1],
        ['B', 1],
        ['B', 0],
        ['A', 0],
        ['A', 1],
        ['B', 1]
    ], columns = ['key', 'cond'])

我想找到每个key的累积(运行)计数(从1开始),我们仅在组中的先前值具有cond == 1时才递增。将其附加到上述数据框后,即可得到

df_result = pd.DataFrame(
    [
        ['A', 1, 1],
        ['A', 1, 2],
        ['B', 1, 1],
        ['B', 0, 2],
        ['A', 0, 3],
        ['A', 1, 3],
        ['B', 1, 2]
    ], columns = ['key', 'cond'])

请注意,基本上每个cond组中最后一行的key值都无效。

只需做一个简单的groupcumcount

df.groupby('key').cumcount()

当然不考虑上一个元素的cond值。如何考虑到这一点?

编辑

由于以下某些解决方案在某些极端情况下不起作用,因此我将提供更全面的数据框架进行测试。

df = pd.DataFrame(
    [
        ['A', 0],
        ['A', 1],
        ['A', 1],
        ['B', 1],
        ['B', 0],
        ['A', 0],
        ['A', 1],
        ['B', 1],
        ['B', 0]
    ], columns = ['key', 'cond'])

在添加真实结果时应该给出的

df_result = pd.DataFrame(
    [
        ['A', 0, 1],
        ['A', 1, 1],
        ['A', 1, 2],
        ['B', 1, 1],
        ['B', 0, 2],
        ['A', 0, 3],
        ['A', 1, 3],
        ['B', 1, 2],
        ['B', 0, 3]
    ], columns = ['key', 'cond'])

3 个答案:

答案 0 :(得分:4)

结合使用groupbyshiftcumsum

df['result'] = df.groupby('key').cond.apply(
        lambda x: x.shift().fillna(1).cumsum()
).astype(int)

df
  key  cond  new
0   A     1    1
1   A     1    2
2   B     1    1
3   B     0    2
4   A     0    3
5   A     1    3
6   B     1    2

答案 1 :(得分:2)

groupby和带有自定义lambda函数的shift用于先前的值,如果可能的话,每个键的第一个值是NaN,最后一个{{3 }}转换为0

int

答案 2 :(得分:1)

df['cnt'] = df[df["cond"]==1].groupby('key').cumcount()+1
df['cnt'] = df.groupby('key')['cnt'].fillna(method='bfill')
df
# =>   key  cond  cnt
#    0   A     1  1.0
#    1   A     1  2.0
#    2   B     1  1.0
#    3   B     0  2.0
#    4   A     0  3.0
#    5   A     1  3.0
#    6   B     1  2.0