在Pandas系列中使用运算符

时间:2018-03-20 19:55:08

标签: pandas

为什么我不能使用in匹配Pandas系列中的字符串?在下面的示例中,第一个评估意外导致False,但第二个评估结果正常。

df = pd.DataFrame({'name': [ 'Adam', 'Ben', 'Chris' ]})
'Adam' in df['name']
'Adam' in list(df['name'])

2 个答案:

答案 0 :(得分:6)

在第一种情况下:

因为in运算符被解释为对df['name'].__contains__('Adam')的调用。如果您查看__contains__pandas.Series的实施情况,您会发现它是以下内容(来自pandas.core.generic.NDFrame):

def __contains__(self, key):
    """True if the key is in the info axis"""
    return key in self._info_axis

因此,您首次使用in被解释为:

'Adam' in df['name']._info_axis 

这预计会提供False,因为df['name']._info_axis实际上包含有关range/index而非数据本身的信息:

In [37]: df['name']._info_axis 
Out[37]: RangeIndex(start=0, stop=3, step=1)

In [38]: list(df['name']._info_axis) 
Out[38]: [0, 1, 2]

在第二种情况下:

'Adam' in list(df['name'])

使用list会将pandas.Series转换为值列表。所以,实际操作是这样的:

In [42]: list(df['name'])
Out[42]: ['Adam', 'Ben', 'Chris']

In [43]: 'Adam' in ['Adam', 'Ben', 'Chris']
Out[43]: True

以下是一些惯用的方法来做你想要的(与相关的速度):

In [56]: df.name.str.contains('Adam').any()
Out[56]: True

In [57]: timeit df.name.str.contains('Adam').any()
The slowest run took 6.25 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 144 µs per loop

In [58]: df.name.isin(['Adam']).any()
Out[58]: True

In [59]: timeit df.name.isin(['Adam']).any()
The slowest run took 5.13 times longer than the fastest. This could mean that an intermediate result is being cached.
10000 loops, best of 3: 191 µs per loop

In [60]: df.name.eq('Adam').any()
Out[60]: True

In [61]: timeit df.name.eq('Adam').any()
10000 loops, best of 3: 178 µs per loop

注意:@Wen在上面的评论中也提出了最后一种方式

答案 1 :(得分:0)

found = df[df['Column'].str.contains('Text_to_search')]
print(len(found))

len(found)将为您提供列中的匹配数。