用一系列元组测试遏制

时间:2017-07-10 10:44:53

标签: python pandas

我有pandas.Series个元组:

s = pd.Series([('a','b','c'), ('a','c','b'), ('c','a','b')])

我想检查('a','b','c')是否在s(或任何其他元组)中。所以:

('a', 'b', 'c') in s

返回False。然而,

('a', 'b', 'c') in s.tolist()

按预期返回True。这是一种优化的熊猫方式吗?转换为列表感觉非常非pythonic。

2 个答案:

答案 0 :(得分:3)

您可以使用equal操作创建bool系列,然后使用any()来获得所需的结果。或者作为一种更全面的方法,您可以使用系列对象的apply()方法,以便对所有项目应用特定功能。然后,您可以使用any()来获得预期结果:

In [28]: (s == ('a', 'b', 'c')).any()
Out[28]: True

In [30]: s.apply(('a', 'b', 'c').__eq__).any()
Out[30]: True

另请注意,由于Series是带有轴标签的一维ndarray,因此对in运算符的成员资格检查将在索引而不是项目上执行。

In [32]: 3 in s
Out[32]: False

In [33]: 2 in s
Out[33]: True

如果您想要更改此行为,可能需要通过创建自己的__contains__类型来覆盖对象的Series方法。

In [39]: class MySeries(pd.Series):
    def __init__(self, *args, **kwargs):
        super(MySeries, self).__init__(*args, **kwargs)
    def __contains__(self, arg):
        return (self == arg).any()            
   ....:     

In [40]: ms = MySeries([('a','b','c'), ('a','c','b'), ('c','a','b')])

In [41]: ('a', 'b', 'c') in ms
Out[41]: True

In [42]: 

In [42]: ('a', 'b', 't') in ms
Out[42]: False

您还可以使其适用于索引和项目:

In [51]: class MySeries(pd.Series):
    def __init__(self, *args, **kwargs):
        super(MySeries, self).__init__(*args, **kwargs)
    def __contains__(self, arg):
        if isinstance(arg, int):
            return super(MySeries, self).__contains__(arg)
        return (self == arg).any()
   ....:     

In [52]: 

In [52]: ms = MySeries([('a','b','c'), ('a','c','b'), ('c','a','b')])

In [53]: 

In [53]: 3 in ms
Out[53]: False

In [54]: 2 in ms
Out[54]: True

In [55]: 

In [55]: ('a', 'b', 'c') in ms
Out[55]: True

In [56]: ('a', 'b', 'd') in ms
Out[56]: False

答案 1 :(得分:2)

您可以使用等式检查(==)和any方法:

(s == ('a', 'b', 'c')).any()

然而,这样你就会失去in提供的短路行为。