2016-06-28 64 views
9

我具有类似于这一个大熊猫帧:查找在大熊猫帧列中的数组元素的位置(又名pd.series)

import pandas as pd 
import numpy as np 

data = {'Col1' : [4,5,6,7], 'Col2' : [10,20,30,40], 'Col3' : [100,50,-30,-50], 'Col4' : ['AAA', 'BBB', 'AAA', 'CCC']} 

df = pd.DataFrame(data=data, index = ['R1','R2','R3','R4']) 

    Col1 Col2 Col3 Col4 
R1  4 10 100 AAA 
R2  5 20 50 BBB 
R3  6 30 -30 AAA 
R4  7 40 -50 CCC 

鉴于目标的数组:

target_array = np.array(['AAA', 'CCC', 'EEE']) 

我想要找到Col4中的单元格索引,这些索引也出现在target_array中。

我试图找到一个记录的答案,但它似乎超出了我的技能......任何人有任何建议?

P.S.顺便说一下,对于这种特殊情况,我可以输入一个目标数组,其元素是数据帧索引名称array(['R1', 'R3', 'R5'])。这样会更容易吗?

编辑1:

非常感谢所有伟大的回复。可悲的是我只能选择一个,但每个人似乎都认为@Divakar是最好的。不过你应该看看piRSquared和MaxU速度比较所有可用

回答

10

您可以使用NumPy's in1d -

df.index[np.in1d(df['Col4'],target_array)] 

说明

1)创建对应于每一行告诉我们是否有col4's元素中的任何元素之间的匹配一个1D面具target_array

mask = np.in1d(df['Col4'],target_array) 

2)使用面膜来选择数据框作为最终输出的有效索引:

out = df.index[np.in1d(df['Col4'],target_array)] 
+0

这样更快! – piRSquared

+0

@piRSquared嗯,我希望是,作为一个NumPy的东西! ;) – Divakar

+0

我一定会记住这一点。 – piRSquared

9

这应该这样做的可能性:

df.loc[df.Col4.isin(target_array)].index 

编辑:

我跑了三个选项:从选定的答案。矿山,布鲁斯·普奇和Divakar

enter image description here

Divakars是由大量的更快。我会选他的。

+0

非常感谢您的比较,这是非常整洁。只有一个问题:你认为数据类型(str)对每种方法的速度有不同影响? – Delosari

+0

它改变了事情的边缘。但订单保持不变。 – piRSquared

+0

这是很好的知道。再次感谢您的回复 – Delosari

5
import pandas as pd 
import numpy as np 

data = {'Col1' : [4,5,6,7], 'Col2' : [10,20,30,40], 'Col3' : [100,50,-30,-50], 'Col4' : ['AAA', 'BBB', 'AAA', 'CCC']} 
target_array = np.array(['AAA', 'CCC', 'EEE']) 

df = pd.DataFrame(data=data, index = ['R1','R2','R3','R4']) 

df['in_col'] = df['Col4'].apply(lambda x: x in target_array) 

这是您要寻找的?然后,您可以对新列进行分组并查询True元素。

+0

非常感谢您提醒我的lambda:我对Python很陌生,这是一个非常强大/灵活的工具 – Delosari

4
df.index[df.Col4.isin(target_array)] 
+0

谢谢您的回复......这是一个非常简洁的方法因为它只使用熊猫功能 – Delosari

7

为了完整起见,我已经添加了两个(.query()变种) - 我的计时对400K行DF:

In [63]: df.shape 
Out[63]: (400000, 4) 

In [64]: %timeit df.index[np.in1d(df['Col4'],target_array)] 
10 loops, best of 3: 35.1 ms per loop 

In [65]: %timeit df.index[df.Col4.isin(target_array)] 
10 loops, best of 3: 36.7 ms per loop 

In [66]: %timeit df.loc[df.Col4.isin(target_array)].index 
10 loops, best of 3: 47.8 ms per loop 

In [67]: %timeit df.query('@target_array.tolist() == Col4') 
10 loops, best of 3: 45.7 ms per loop 

In [68]: %timeit df.query('@target_array in Col4') 
10 loops, best of 3: 51.9 ms per loop 

Here is a similar comparison for (not in ...) and for different dtypes

+1

非常感谢您的查询选项,这是一个非常好的发现 – Delosari