Pandas - 识别以列表中的值开头的数据帧值

时间:2016-10-14 21:04:08

标签: python pandas

说我有以下数据框:

>>> vals=['123','76']

并说我有3个感兴趣的值:

>>> d.isin(vals)
       A      B      C
0  False  False  False
1  False  False  False
2   True  False  False
3  False  False  False
>>> 

我有兴趣确定数据框中的哪些值以列表中的任何值开头。在我的例子中有3个案例:(0,A)以123开头; (1,A)以123开头; (2,A)以76开头。

有没有办法可以在不循环遍历每个值的情况下执行此操作?

如果我对匹配值感兴趣,我可以这样做:

>>> d.applymap(lambda x:x.startswith('123'))
       A      B      C
0   True  False  False
1   True  False  False
2  False  False  False
3  False  False  False
>>> 

如果我对这些值是否以1个特定值开始感兴趣,我可以这样做:

{{1}}

但是如何将这两者结合起来找到以列表中的任何值开头的任何值?

3 个答案:

答案 0 :(得分:3)

你可以这样做:

d.applymap(lambda x: any([x.startswith(v) for v in vals]))

答案 1 :(得分:1)

替代解决方案,它不使用.apply()

In [66]: search_re = '^(?:{})'.format('|'.join(vals))

In [67]: search_re
Out[67]: '^(?:123|76)'

In [69]: df.astype(str).stack().str.match(search_re).unstack()
Out[69]:
       A      B      C
0   True  False  False
1   True  False  False
2   True  False  False
3  False  False  False

答案 2 :(得分:0)

有点复杂,但似乎是最快的解决方案。

您可以使用仅适用于系列的str.startswith,因此请使用list理解和concat输出。但是需要检查列表vals中的更多项目,因此请使用numpy.logical_orreduce合并numpy array的其他列表理解 - 转换concat的输出并最后创建Dataframe具有与原始列表和索引相同的列和索引numpy.logical_or

print ([pd.concat([d[col].str.startswith(i) for col in d], axis=1).values for i in vals])
[array([[ True, False, False],
       [ True, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool), array([[False, False, False],
       [False, False, False],
       [ True, False, False],
       [False, False, False]], dtype=bool)]

print (np.logical_or.reduce(
      [pd.concat([d[col].str.startswith(i) for col in d], axis=1).values for i in vals]))
[[ True False False]
 [ True False False]
 [ True False False]
 [False False False]]

print(pd.DataFrame(np.logical_or.reduce(
      [pd.concat([d[col].strstartswith(i) for col in d], 
                 axis=1).values for i in vals]), 
                   index=d.index, columns=d.columns))

       A      B      C
0   True  False  False
1   True  False  False
2   True  False  False
3  False  False  False

<强>计时

#[40000 rows x 3 columns]
d = pd.concat([d]*10000).reset_index(drop=True)


In [77]: %timeit (d.applymap(lambda x: any([x.startswith(v) for v in vals])))
1 loop, best of 3: 228 ms per loop

In [78]: %timeit (d.apply(lambda x: x.str.contains('|'.join(['^' + x for x in vals]))))
10 loops, best of 3: 147 ms per loop

In [79]: %timeit (d.astype(str).stack().str.match('^(?:{})'.format('|'.join(vals))).unstack())
10 loops, best of 3: 172 ms per loop

In [80]: %timeit (pd.DataFrame(np.logical_or.reduce([pd.concat([d[col].str.startswith(i) for col in d], axis=1).values for i in vals]), index=d.index, columns=d.columns))
10 loops, best of 3: 116 ms per loop