如何在pandas DataFrame的一列中计算数字1出现的次数

4

在数据框中,我有一个名为flag的列,我想要计算该列中1的组数。

df=pd.DataFrame({'flag':[1,1,0,1,0,1,1,0,1,1,1]}) 


df_out=pd.DataFrame({'groups_of_one_count':[4]}) 
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5

为了提高性能,使用NumPy而没有进行任何追加/连接操作 -

a = df.flag.values
out = (a[1:]>a[:-1]).sum() + (a[0]==1)
说明:我们寻找下一个元素大于前一个元素。如果满足条件,则信号开始一个岛屿/组1s。我们仅将求和作为最终输出。对于特殊情况,当这样的一组从第一个元素开始时,我们将其单独捕获。

给定示例的时间按比例缩放10000x -

In [64]: df=pd.DataFrame({'flag':[1,1,0,1,0,1,1,0,1,1,1]})

In [65]: df = pd.concat([df]*10000)

# @Quang Hoang's soln
In [66]: %timeit (np.diff(np.append(df.flag.values,0)) == -1).sum()
362 µs ± 26.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# From this post
In [67]: %%timeit   
    ...: a = df.flag.values
    ...: out = (a[1:]>a[:-1]).sum() + (a[0]==1)
191 µs ± 5.4 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# @jezrael's soln
In [68]: %timeit (df['flag'].ne(df['flag'].shift()) & df['flag'].eq(1)).sum()
1.39 ms ± 8.86 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

# @YOBEN_S's soln
In [69]: %timeit df[df.flag.ne(0)].index.to_series().diff().ne(1).sum()
2.92 ms ± 209 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

通用情况(除了0和1之外可能还有其他数字)

解决方案将会进行修改,变为获取要搜索的数字的掩码(这里是1),并对其进行操作 -

a = df.flag.values
m = a==1
out = (m[1:] & ~m[:-1]).sum() + m[0]

根据我的测试(超过10k个随机样本),这并不更快,甚至稍微慢一些。 - Quang Hoang
@QuangHoang 已添加了使用10k倍增量数据集的时间记录。 - Divakar
1
是的,瓶颈在于 df.flag[0]。此外,+a[0]就足够了,而且比 + (a[0]==1) 快一点。 - Quang Hoang

3

这个想法是使用ne(不相等)逐一比较元素组,并利用Series.shift方法筛选出仅包含组中有 1 的组:

a = (df['flag'].ne(df['flag'].shift()) & df['flag'].eq(1)).sum()
print (a)
4

df_out=pd.DataFrame({'groups_of_one_count':[a]}) 
print (df_out)
   groups_of_one_count
0                    4

详情:

print (df.assign(consec=df['flag'].ne(df['flag'].shift()),
                 eq1 = df['flag'].eq(1),
                 chained = (df['flag'].ne(df['flag'].shift()) & df['flag'].eq(1))
       ))
    flag  consec    eq1  chained
0      1    True   True     True
1      1   False   True    False
2      0    True  False    False
3      1    True   True     True
4      0    True  False    False
5      1    True   True     True
6      1   False   True    False
7      0    True  False    False
8      1    True   True     True
9      1   False   True    False
10     1   False   True    False

3

使用纯 NumPy 可以提高性能:

(np.diff(np.append(df.flag.values,0)) == -1).sum()

想法: 统计数据从10跳转的次数。我们使用np.append为以1结尾的系列添加一个后续的0,以便包含最后一个块。


3

首先,我们选择不等于0的index,然后找到diff的索引。如果diff不连续(这里不等于1),那就是不同的组:

df[df.flag.ne(0)].index.to_series().diff().ne(1).sum()
4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,