在DataFram中按行计算非零值的非重叠运行

2024-05-03 03:12:24 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有以下熊猫DataFrame

id | a1 | a2 | a3 | a4 
1  | 3  | 0  | 10 | 25   
2  | 0  | 0  | 31 | 15  
3  | 20 | 11 | 6  | 5  
4  | 0  | 3  | 1  | 7  

我要计算的是,对于n的不同值,每行中n连续非零值的非重叠运行次数。预期输出为:

^{pr2}$

例如,2s列中的每个值显示该行中长度为2的非重叠运行数,3s列中的每个值显示长度为3的相应运行数,依此类推。在

我想知道有没有什么熊猫或裸体的方法来处理这个问题?在


Tags: 方法ida2dataframea1次数a3a4
2条回答

管理非重叠功能的解决方案。在

def count(row,mins):
    runs=(row!=0).astype(uint8).tobytes().decode().split(chr(0))
    lengths=[len(run) for run in runs]
    return np.floor_divide.outer(lengths,mins).sum(0) 

它使用strings-fast操作来查找所有的运行,然后使用//来查找每个给定长度的不重叠的运行数。在

使用df:

^{pr2}$

np.apply_along_axis(count,1,df,[2,3,4])返回

array([[1, 0, 0],
       [1, 0, 0],
       [2, 1, 1],
       [1, 1, 0]], dtype=int32)

这是df的预期结果。在

这里有一种使用^{}来解决行中任意数量元素的方法-

from scipy.signal import convolve2d as conv2

n = 6
v = np.vstack([(conv2(df.values!=0,[[1]*I])==I).sum(1) for I in range(2,n+1)]).T
df_v = pd.DataFrame(v, columns = [[str(i)+'s' for i in range(2,n+1)]])
df_out = pd.concat([df, df_v],1)

基本思路

其基本思想是我们可以使用滑动窗口对每行中存在的非零进行求和。假设我们在看有多少三个非零连续出现。因此,我们将使用一个大小为3的滑动窗口并得到滑动求和。所有那些滑动窗口中所有三个元素都是非零的地方将产生一个3的总和。因此,我们寻找匹配3的求和并对其进行计数。就这样!我们遍历所有窗口大小来捕获2s3s等所有窗口

下面是一个在数组上计数3s的示例运行-

^{pr2}$

样本运行-

In [158]: df_out
Out[158]: 
   a1  a2  a3  a4  a5  a6  2s  3s  4s  5s  6s
0   1   2   1   0   0   2   2   1   0   0   0
1   1   1   2   1   0   1   3   2   1   0   0
2   1   1   0   0   1   1   2   0   0   0   0
3   2   2   1   0   2   2   3   1   0   0   0

请注意,如果第一列是'id',那么我们需要跳过它。因此,我们需要在建议的解决方案代码中使用df.values[:,1:],而不是{}。在

相关问题 更多 >