我有一个如下所示的数据帧:
ID 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89 90 total
-----------------------------------------------------------------------------------------------------
0 A 2 21 0 18 3 0 0 0 2 ... 0 0 0 0 0 0 0 0 0 0 156
1 B 0 20 12 2 0 8 14 23 0 ... 0 0 0 0 0 0 0 0 0 0 231
2 C 0 38 19 3 1 3 3 7 1 ... 0 0 0 0 0 0 0 0 0 0 78
3 D 3 0 0 1 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 5
我想知道在第一个长度为n的零序列出现在每一行之前和之后的事件百分比(单元格中的数字)。这个问题是从这里发现的另一个问题开始的:Length of first sequence of zeros of given size after certain column in pandas dataframe,我正试图修改代码以满足我的需要,但我不断地出错,似乎找不到正确的方法。这就是我尝试过的:
def func(row, n):
"""Returns the number of events before the
first sequence of 0s of length n is found
"""
idx = np.arange(0, 91)
a = row[idx]
b = (a != 0).cumsum()
c = b[a == 0]
d = c.groupby(c).count()
#in case there is no sequence of 0s with length n
try:
e = c[c >= d.index[d >= n][0]]
f = str(e.index[0])
except IndexError:
e = [90]
f = str(e[0])
idx_sliced = np.arange(0, int(f)+1)
a = row[idx_sliced]
if (int(f) + n > 90):
perc_before = 100
else:
perc_before = a.cumsum().tail(1).values[0]/row['total']
return perc_before
实际上,我得到的错误是:
---> perc_before = a.cumsum().tail(1).values[0]/row['total']
TypeError: ('must be str, not int', 'occurred at index 0')
最后,我将把这个函数应用于一个数据帧,并返回一个新的列,在每行的第一个n0序列之前包含%的事件,如下所示:
ID 0 1 2 3 4 5 6 7 8 ... 81 82 83 84 85 86 87 88 89 90 total %_before
---------------------------------------------------------------------------------------------------------------
0 A 2 21 0 18 3 0 0 0 2 ... 0 0 0 0 0 0 0 0 0 0 156 43
1 B 0 20 12 2 0 8 14 23 0 ... 0 0 0 0 0 0 0 0 0 0 231 21
2 C 0 38 19 3 1 3 3 7 1 ... 0 0 0 0 0 0 0 0 0 0 78 90
3 D 3 0 0 1 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 5 100
如果试图解决此问题,可以使用以下示例输入进行测试:
a = pd.Series([1,1,13,0,0,0,4,0,0,0,0,0,12,1,1])
b = pd.Series([1,1,13,0,0,0,4,12,1,12,3,0,0,5,1])
c = pd.Series([1,1,13,0,0,0,4,12,2,0,5,0,5,1,1])
d = pd.Series([1,1,13,0,0,0,4,12,1,12,4,50,0,0,1])
e = pd.Series([1,1,13,0,0,0,4,12,0,0,0,54,0,1,1])
df = pd.DataFrame({'0':a, '1':b, '2':c, '3':d, '4':e})
df = df.transpose()
尝试一下:
结果:
对于完整帧,使用
ncols=91
调用apply
另一种可能的解决办法:
印刷品:
由于上一个问题的一个评论是关于速度的,我想你可以尝试将问题矢量化。我使用此数据帧尝试(与原始输入略有不同):
现在我想的是链接命令来创建一个掩码并找到数据不等于0的地方,然后沿列轴使用
cumsum
,并查看沿列的diff
等于0的地方。要找到第一个,可以使用cummax
,这样(按行)之后的所有列都被认为是True
。使用与此掩码相反的掩码屏蔽原始数据帧,沿列求和并除以总和。例如,n=2时:在您的情况下,您需要通过
range(91)
更改range(9)
来获取所有列相关问题 更多 >
编程相关推荐