有没有一种更快的方法来计算熊猫系列中元素的出现?

时间:2019-08-21 09:52:34

标签: python pandas

我正在尝试同步及时发生的由布尔计数器标识的事件(0个无事件,1个事件)。 例如像

的形式

[0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0,0,0,1, 1,1]

我无法更改此格式。 我想做的是通过为连续事件分配连续的编号来区分连续事件。因此,上一个列表的输出为:

[0,0,0,0,1,1,1,1,1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3, 3,3]

目前,我发现了两种实现请求结果的方法,但是我想知道是否可以找到一种更清洁,更好和更快的方法。 列表的长度可能超过1k个数字,而并非总是按特定顺序排列,或者连续0或1s的长度也可能不止一个。

一个真实的例子是:

test = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
        0, 0, 0, 
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
testdf = pd.DataFrame()
testdf['test'] = test
%%timeit
supplist = []
i=0
for row in testdf['test']:
    if row == 0:
        supplist.append(0)
    elif row == 1:
        if supplist[i-1]==0:
            supplist.append(max(supplist)+1)
        elif supplist[i-1] == max(supplist):
            supplist.append(max(supplist))    
    i+=1
testdf['Count'] = supplist

每个循环10.4 ms±193 µs(平均±标准偏差,共运行7次,每个循环100个循环)

%%timeit
testdf['PandasCount'] = testdf['test'].diff().fillna(0).abs().cumsum().apply(lambda x: 0 if x%2==0 else x).apply(lambda x: (x+1)/2 if x>0 else x)

每个循环2.98 ms±206 µs(平均±标准偏差,共运行7次,每个循环100个循环)

testdf.describe()

测试平均值0.909615

计数平均值5.546154

PandasCount平均为5.546154

测试标准0.287008

计数std 3.457669

PandasCount标准3.457669

提前谢谢!

0 个答案:

没有答案