75

我有两个系列s1s2熊猫,想计算交集,即系列的所有值都是共同的。

我将如何使用该concat功能来做到这一点?我一直在尝试解决它,但一直无法解决(我不想计算 和 的索引上的交集s1s2而是计算值上的交集)。

4

6 回答 6

85

将这两个系列放在 Python 的set 容器中,然后使用 set intersection 方法:

s1.intersection(s2)

然后在需要时转换回列表。

刚刚注意到标签中的熊猫。可以翻译回:

pd.Series(list(set(s1).intersection(set(s2))))

从评论中,我将其更改为更 Pythonic 的表达式,它更短且更易于阅读:

Series(list(set(s1) & set(s2)))

应该可以解决问题,除非索引数据对您也很重要。

在转到 pd.Series 之前添加了list(...)翻译集合,因为 pandas 不接受集合作为系列的直接输入。

于 2013-08-06T12:05:28.283 回答
46

设置:

s1 = pd.Series([4,5,6,20,42])
s2 = pd.Series([1,2,3,5,42])

时间:

%%timeit
pd.Series(list(set(s1).intersection(set(s2))))
10000 loops, best of 3: 57.7 µs per loop

%%timeit
pd.Series(np.intersect1d(s1,s2))
1000 loops, best of 3: 659 µs per loop

%%timeit
pd.Series(np.intersect1d(s1.values,s2.values))
10000 loops, best of 3: 64.7 µs per loop

values因此,如果明确使用 numpy 解决方案,即使对于小型系列,numpy 解决方案也可以与 set 解决方案相媲美。

于 2014-01-16T23:33:17.067 回答
19

如果您使用的是 Pandas,我假设您也在使用 NumPy。Numpy 具有intersect1d适用于 Pandas 系列的功能。

例子:

pd.Series(np.intersect1d(pd.Series([1,2,3,5,42]), pd.Series([4,5,6,20,42])))

将返回一个值为 5 和 42 的系列。

于 2013-08-06T12:26:44.563 回答
15

Python

s1 = pd.Series([4,5,6,20,42])
s2 = pd.Series([1,2,3,5,42])

s1[s1.isin(s2)]

R

s1  <- c(4,5,6,20,42)
s2 <- c(1,2,3,5,42)

s1[s1 %in% s2]

编辑:不处理骗子。

于 2015-08-25T21:03:41.777 回答
3

可以使用如下的合并运算符

pd.merge(df1, df2, how='inner')
于 2016-10-16T20:51:47.227 回答
0

这是通过检查左右夹杂物的另一种解决方案

import pandas as pd

def intersect(left, right):
    left, right = pd.Series(pd.unique(left)), pd.Series(pd.unique(right))
    right = right.loc[right.isin(left)]
    left  =  left.loc[left.isin(right)]
    return pd.Series(pd.unique(left))

left = pd.Series([1,2,pd.NA, pd.NA, pd.NA], index=[*"abcde"], dtype="Int32")
right = pd.Series([pd.NA, pd.NA, 1, 3], index=[*"efgh"], dtype="Int32")
intersect(left, right)

这有两个主要优点:

  • 它适用于pandas Int32和其他可为空的数据类型。如果您的列包含pd.NA然后np.intersect1d引发错误!

  • 它使 pandas dtype 保持完整

于 2020-11-22T17:33:56.070 回答