Pandas基于标准的计数

ctrmrzij  于 2023-03-28  发布在  其他
关注(0)|答案(1)|浏览(99)

我有一个pandas DataFrame

d={'gen':['A','A','A','A','B','B','B','B','C','D','D','D','D','D','D','D','D','D','D'], 'diff':pd.Series([1,1,1,1,2,1,1,1,1,1,1,1,1,2,2,1,1,1], index=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])}
wk = pd.DataFrame(data=d, index=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18])

我的目标是根据diff计算gen的出现次数,并使用一些标准:
1.计数diff是否为1,以及
1.索引i处的gen等于索引i+1处的gen,以及
1.如果有连续的1,那么计数将是这样的:if(number of consecutive 1)%2 == 0:计数=连续数/2,如果不是:count =(连续次数-1)/2
有了这段代码,我可以实现我想要的:

k=0
j=0
z={}
for i in range(wk.shape[0]):
    if wk['diff'][i] == 1:
        if wk['gen'][i] == wk['gen'][i+1]:
            if j == 0:
                j+=2
            if j%2==0:
                k+=1                
            if j>=2:
                j+=1
            z[wk['gen'][i]] = k
        if wk['gen'][i] != wk['gen'][i+1]:
            j=0
            k=0

字典z的结果是:{'A': 2, 'B': 1, 'D': 4}
但是当我使用更大的数据(超过410,000条记录)时,当索引i处的gen不等于索引i+1处的gen时,计数器并不总是从0开始。我使用的数据是:link我的代码有什么问题?

t40tm48m

t40tm48m1#

使用groupby.count计算每组连续的1,执行floordiv乘以2(相当于您的x/2 if x%2==0 else (x-1)/2),并在转换to_dict之前再次使用groupby.sum进行聚合:

group = wk['diff'].ne(wk.groupby('gen')['diff'].shift()).cumsum()
m = wk['diff'].eq(1)

out = (wk[m].groupby(['gen', group])      # keep only 1s and group
             ['diff'].count().floordiv(2) # count and floor division
            .groupby(level='gen').sum()   # sum per "gen" group
            .loc[lambda x: x>0].to_dict() # only counts > 0 and convert to dict
      )

输出:

{'A': 2, 'B': 1, 'D': 3}
中间体

groupm

gen  diff  group      m
0    A   1.0      1   True
1    A   1.0      1   True
2    A   1.0      1   True
3    A   1.0      1   True
4    B   2.0      2  False
5    B   1.0      3   True
6    B   1.0      3   True
7    B   1.0      3   True
8    C   1.0      4   True
9    D   1.0      5   True
10   D   1.0      5   True
11   D   1.0      5   True
12   D   1.0      5   True
13   D   2.0      6  False
14   D   2.0      6  False
15   D   1.0      7   True
16   D   1.0      7   True
17   D   1.0      7   True
18   D   NaN      8  False

相关问题