Pandas dataframe列包含列表,Get连续两行

时间:2015-10-20 08:51:35

标签: python pandas

我有以下数据框:

values with

我想检查一行中有多少elemnet与前一行相同。我的输出应如下所示:

timestmp              coulmnis                                                
2015-10-15 18:24:00  set([a,b,c,d,e,f])
2015-10-15 18:27:00  set([a,b,g,h,i])
2015-10-15 18:30:00  set([g,h,j,k,l])
2015-10-15 18:33:00  set([a,b,g,h,j,k,l])
2015-10-15 18:36:00  set([d,e,j,k])

什么是最有效的方式,以便我可以避免for循环。任何帮助赞赏!!

编辑:

timestmp              coulmnis                   count_sameAsPrevious                          
2015-10-15 18:24:00  set([a,b,c,d,e,f])          0
2015-10-15 18:27:00  set([a,b,g,h,i])            2
2015-10-15 18:30:00  set([g,h,j,k,l])            2
2015-10-15 18:33:00  set([a,b,g,h,j,k,l])        5
2015-10-15 18:36:00  set([d,e,j,k])              2

现在我想使用df['shiftedColumn'] = df.columnis.shift(1) df = df.dropna() 在包含len(filter(y.__contains__,x))的两列中获取相同的元素。

2 个答案:

答案 0 :(得分:3)

您可以使用DataFrame.shift()执行此操作,将行移动一列,然后将coulmnis列重命名为其他内容,然后重置索引并合并timestmp上的数据框,然后使用DataFrame上的apply()。示例(在一行中) -

df['count'] = df.reset_index().merge(df.shift(1).reset_index().rename(columns={'coulmnis':'newcol'})) \
                .set_index('timestmp').apply((lambda x: len(x['coulmnis'] & x['newcol']) if pd.notnull(x['newcol']) else 0),axis=1)

以更易读的方式举例 -

mergedf = df.shift(1).reset_index().rename(columns={'coulmnis':'newcol'})
newdf = df.merge(mergedf).set_index('timestmp')
df['count'] = newdf.apply((lambda x: len(x['coulmnis'] & x['newcol']) if pd.notnull(x['newcol']) else 0),axis=1)

演示 -

In [36]: df
Out[36]:
                                       coulmnis
timestmp
2015-10-15 18:24:00     set([f, b, c, e, d, a])
2015-10-15 18:27:00        set([g, b, i, a, h])
2015-10-15 18:30:00        set([l, g, k, j, h])
2015-10-15 18:33:00  set([b, j, h, k, a, l, g])
2015-10-15 18:36:00           set([d, e, k, j])

In [38]: df['count'] = df.reset_index().merge(df.shift(1).reset_index().rename(columns={'coulmnis':'newcol'})) \
   ....:                 .set_index('timestmp').apply((lambda x: len(x['coulmnis'] & x['newcol']) if pd.notnull(x['newcol']) else 0),axis=1)

In [39]: df
Out[39]:
                                       coulmnis  count
timestmp
2015-10-15 18:24:00     set([f, b, c, e, d, a])      0
2015-10-15 18:27:00        set([g, b, i, a, h])      2
2015-10-15 18:30:00        set([l, g, k, j, h])      2
2015-10-15 18:33:00  set([b, j, h, k, a, l, g])      5
2015-10-15 18:36:00           set([d, e, k, j])      2

答案 1 :(得分:2)

我的解决方案:

df = pandas.DataFrame({'sets': [set(['a','b','c','d','e','f']), set(['a','b','g','h','i']), set(['g','h','j','k','l']), set(['a','b','g','h','j','k','l'])]})
df['sets_temp'] = pandas.Series([])
df['sets_temp'][1:] = df['sets'][:-1]
df['count'] = pandas.Series([])
df['count'][1:] = df[1:].apply(lambda row: len(row['sets'] & row['sets_temp']), axis=1)
df['count'][:1] = 0
df = df.drop('sets_temp', axis=1)

输出:

>>> df
                         sets  count
0     set([b, c, d, e, a, f])      0
1        set([b, h, i, a, g])      2
2        set([j, h, l, k, g])      2
3  set([j, b, h, k, l, a, g])      5

实际上apply()函数是for loop的包装器,因此apply()的效率是相同的,但看起来没有机会逃避使用类似循环的方法