python - 计算 Pandas 滚动交叉点的大小

标签 python pandas

我有一个 dataframe,它由组标签 ('B') 和每个组的元素 ('A') 组成。组标签是有序的,我想知道我在组 i+1 中出现了多少组元素。

一个例子:

df= pd.DataFrame({ 'A': ['a','b','c','a','c','a','d'], 'B' : [1,1,1,2,2,3,3]})

   A  B
0  a  1
1  b  1
2  c  1
3  a  2
4  c  2
5  a  3
6  d  3

所需的输出类似于:

B
1  NaN
2  2
3  1

解决此问题的一种方法是计算组 I 和组 i+1 的并集中不同元素的数量,然后减去每个组中不同元素的数量。我试过:

pd.rolling_apply(grp['A'], lambda x: len(x.unique()),2)

但这会产生错误:

AttributeError: 'Series' object has no attribute 'type'

我如何让它与 rolling_apply 一起工作,或者有更好的方法来解决这个问题吗?

最佳答案

一种使用集合并移动结果的方法:

首先对dataframe进行分组,然后将每组的A列转换为一个集合:

In [86]: grp = df.groupby('B')
In [87]: s = grp.apply(lambda x : set(x['A']))
In [88]: s
Out[88]: 
B
1    set([a, c, b])
2       set([a, c])
3       set([a, d])
dtype: object

要计算连续集合之间的交集,请制作一个移位版本(我将 NaN 替换为下一步的空集合):

In [89]: s2 = s.shift(1).fillna(set([]))
In [90]: s2
Out[90]: 
B
1           set([])
2    set([a, c, b])
3       set([a, c])
dtype: object

合并两个系列并计算交集的长度:

In [91]: s.combine(s2, lambda x, y: len(x.intersection(y)))
Out[91]: 
B
1    0
2    2
3    1
dtype: object

完成最后一步的另一种方法(对于集合 & 表示 intersection):

df = pd.concat([s, s2], axis=1)
df.apply(lambda x: len(x[0] & x[1]), axis=1)

滚动应用不起作用的原因是 1) 您为其提供了一个 GroupBy 对象而不是一个系列,并且 2) 它仅适用于数值。

关于python - 计算 Pandas 滚动交叉点的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22465496/

相关文章:

python - 将文件夹的多个 csv 文件加载到一个数据框中

python:获取操作系统的argv[0],而不是sys.argv[0]

python - 一定时间后继续 for 循环

python - 根据唯一的列值创建列并填充

python pandas-将带有两个参数的函数应用于列

python - 将 DataFrame 对象转换为字符串或对齐 DataFrame 编码

python - 填充洗牌缓冲区时,Google Colaboratory session 突然结束

Python寻找第N个素数

python - Pandas :从数据框中选择列

python - Pandas 中的日期滞后