2017-08-04 80 views
3

您会在问题结尾找到具有可重复输入的片段以及期望输出的示例。识别并计算熊猫数据框中的独特模式

挑战:

我有这样一个数据帧:

enter image description here

数据框有这样的1和0的模式两列:

enter image description here

或者这个:

enter image description here

列的数量会有所不同,模式的长度也会不同。 但是,数据框中的唯一数字将为0或1.

我想识别这些模式,计算它们的每次出现次数,然后构建包含结果的数据帧。为了简化整个事情,我想专注于,并忽略。在这种特定情况下所需的输出将是:在column_A

enter image description here

我想的程序,以确定,作为一个例子,图案[1,1,1]发生两次,而不是完全在column_B中。请注意,我已将这些模式的总和用作数据框中的索引。

重现输入:

import pandas as pd 
df = pd.DataFrame({'column_A':[1,1,1,0,0,0,1,0,0,1,1,1], 
        'column_B':[1,1,1,1,1,0,0,0,1,1,0,0]}) 

colnames = list(df) 
df[colnames] = df[colnames].apply(pd.to_numeric) 
datelist = pd.date_range(pd.datetime.today().strftime('%Y-%m-%d'), periods=len(df)).tolist() 
df['dates'] = datelist 
df = df.set_index(['dates']) 
print(df) 

所需的输出:

df2 = pd.DataFrame({'pattern':[5,3,2,1], 
       'column_A':[0,2,0,1], 
       'column_B':[1,0,1,0]}) 
df2 = df2.set_index(['pattern']) 
print(df2) 

我尝试至今:

我一直在努力寻找解决方案,其中包括嵌套for循环,我计算runnin g每次观测值等于零时重置的总和。它还包括诸如df.apply(lambda x: x.value_counts())之类的功能。但至少可以说,至少不是100%正确。

谢谢你的任何其他建议!

+1

也许这个是类似的:https:// stackoverflow。com/questions/42555031/pandas-find-sequence-or-pattern-in-column – Moritz

回答

2

这里是我的尝试:

def fun(ser): 
    ser = ser.dropna() 
    ser = ser.diff().fillna(ser) 
    return ser.value_counts() 


df.cumsum().where((df == 1) & (df != df.shift(-1))).apply(fun) 
Out: 
    column_A column_B 
1.0  1.0  NaN 
2.0  NaN  1.0 
3.0  2.0  NaN 
5.0  NaN  1.0 

第一部分(df.cumsum().where((df == 1) & (df != df.shift(-1))))产生的累计总和:

  column_A column_B 
dates       
2017-08-04  NaN  NaN 
2017-08-05  NaN  NaN 
2017-08-06  3.0  NaN 
2017-08-07  NaN  NaN 
2017-08-08  NaN  5.0 
2017-08-09  NaN  NaN 
2017-08-10  4.0  NaN 
2017-08-11  NaN  NaN 
2017-08-12  NaN  NaN 
2017-08-13  NaN  7.0 
2017-08-14  NaN  NaN 
2017-08-15  7.0  NaN 

所以,如果我们忽略了NaN,并且采取差异列表,我们可以有值。这就是函数的作用:它会抛出NaN,然后​​取出差异,所以它不再是累计和。它最终返回值计数。

+1

感谢您找到时间来解释解决方案中的细节! – vestland