我有以下数据框:
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))
的两列中获取相同的元素。
答案 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()
的效率是相同的,但看起来没有机会逃避使用类似循环的方法