我正在遍历多个熊猫数据帧,在每次迭代中我提取2个列表。 然后,对于每个2个列表组合,我需要在另一个数据框中找到该行,其中出现2个列表中所有值的每种组合。
简化示例:
df如下所示(任何D_val P_val只能出现一次):
D_val | P_val | D_PCode
A | 1 | 25
D | 1 | 21
C | 2 | 32
B | 4 | 35
D | 2 | 126
B | 1 | 3
C | 1 | 312
对于具有以下列表的单次迭代-
list1 = [1,2]
list2 = [A,B,C]
我希望获得以下列表:
[25,3,312,32]
说明:
for [A,1] - 25
for [A,2] - nothing
For [B,1] - 3
等
我使用嵌套循环来实现它,但是由于多次迭代,大型数据帧和长列表,它花费的时间太长。
任何建议如何有效实施?如果需要,我很高兴使用其他数据结构。
答案 0 :(得分:2)
您可以使用itertools.product生成所有可能的值,然后使用isin:
packages.config
输出
from itertools import product
import pandas as pd
data = [['A', 1, 25],
['D', 1, 21],
['C', 2, 32],
['B', 4, 35],
['D', 2, 126],
['B', 1, 3],
['C', 1, 312]]
df = pd.DataFrame(data=data, columns=['D_val', 'P_val', 'D_PCode'])
list1 = [1, 2]
list2 = ['A', 'B', 'C']
lookup = set(product(list2, list1))
mask = df[['D_val', 'P_val']].apply(tuple, axis=1).isin(lookup)
result = df[mask].D_PCode
print(result)
或者直接在两个列上直接使用isin,例如:
0 25
2 32
5 3
6 312
Name: D_PCode, dtype: int64
输出
list1 = [1, 2]
list2 = ['A', 'B', 'C']
result = df[df.D_val.isin(list2) & df.P_val.isin(list1)].D_PCode
print(result)
答案 1 :(得分:2)
我们仅两次使用isin
df1=df.loc[df.D_val.isin(list2)&df.P_val.isin(list1)]
df1
Out[211]:
D_val P_val D_PCode
0 A 1 25
2 C 2 32
5 B 1 3
6 C 1 312
答案 2 :(得分:1)
这是一个MultiIndex
问题,最好通过reindex
解决。
df = df.set_index(['D_val', 'P_val'])
idx = pd.MultiIndex.from_product([list2, list1])
df.reindex(idx)
D_PCode
A 1 25.0
2 NaN
B 1 3.0
2 NaN
C 1 312.0
2 32.0
如果要使用匹配项的字典,请使用reindex
+ Series.to_dict
:
df.reindex(idx).D_PCode.to_dict()
{('A', 1): 25.0,
('A', 2): nan,
('B', 1): 3.0,
('B', 2): nan,
('C', 1): 312.0,
('C', 2): 32.0}
如果只希望存在的行,请使用intersection
来有效地计算相交的索引:
df.loc[df.index.intersection(idx)]
D_PCode
A 1 25
B 1 3
C 1 312
2 32