我有一个数据框:df1
SAP_Name SAP_Class SAP_Sec
Avi 5 Avi
Rison 6 A
Slesh 7 B
San 8 C
Sud 7 B
df2:
Name_Fi Class std
Avi 5 fgh
Rison 6 Rij
Slesh 7 jkh
我正在尝试根据2个数据帧的列中包含的值来获取标头的映射。
使用以下代码时:
dfs1 = {col1: df1[col1].drop_duplicates() for col1 in df1.columns}
set2 = {col2: set(df2[col2]) for col2 in df2.columns}
d = {}
for col2, v2 in set2.items():
for col1, v1 in dfs1.items():
cond = set(v2).issubset(v1)
if cond:
d[col2] = col1
print(d)
我得到一个结果:
{'Name_Fi': 'SAP_Name', 'Class': 'SAP_Class'}
所需的输出:
{'Name_Fi': ['SAP_Name','SAP_Sec'], 'Class': 'SAP_Class'}
基本上尝试在df1中有匹配值的任何地方打印每个匹配的列标题。胸膜肺炎可以帮助吗?
答案 0 :(得分:1)
我认为在intersection
之间需要set
,因此为了提高性能,dict comprehension
将字典的两个值都转换为set
s:
from collections import defaultdict
dfs1 = {col1: set(df1[col1].drop_duplicates()) for col1 in df1.columns}
set2 = {col2: set(df2[col2]) for col2 in df2.columns}
d = defaultdict(list)
for col2, v2 in set2.items():
for col1, v1 in dfs1.items():
cond = v2.intersection(v1)
if cond:
d[col2].append(col1)
print(d)
defaultdict(<class 'list'>, {'Name_Fi': ['SAP_Name', 'SAP_Sec'], 'Class': ['SAP_Class']})
答案 1 :(得分:1)
您不是在这里寻找issubset
,因为这仅在一列中的值是另一列中的值的子集(例如, 所有 df2['Name_Fi']
的值包含在df1['SAP_Sec']
中。相反,您可以使用set.intersection
或语法糖&
来检查是否存在是任何重叠。
您可以将此想法与collections.defaultdict
结合使用,以提取所需的结果:
from collections import defaultdict
d = defaultdict(list)
for col2, v2 in set2.items():
for col1, v1 in dfs1.items():
cond = set(v2) & set(v1)
if cond:
d[col2].append(col1)
print(d)
defaultdict(<class 'list'>, {'Name_Fi': ['SAP_Name', 'SAP_Sec'],
'Class': ['SAP_Class']})
更有效地,您可以在理解中计算set
个对象,以避免在嵌套循环中进行显式转换:
from collections import defaultdict
dfs1 = {col1: set(df1[col1]) for col1 in df1}
set2 = {col2: set(df2[col2]) for col2 in df2}
d = defaultdict(list)
for col2, v2 in set2.items():
for col1, v1 in dfs1.items():
if v2 & v1:
d[col2].append(col1)
print(d)
对于更大的数组,您可能会发现将pd.Series.unique
+ any
与生成器表达式结合使用会更有效:
import pandas as pd
import numpy as np
np.random.seed(0)
A = pd.Series(np.random.randint(0, 1000, 10000)).unique()
B = pd.Series(np.random.randint(0, 100000, 10000)).unique()
%timeit np.in1d(B, A).any() # 1.1 ms per loop
%timeit set(A) & set(B) # 1.46 ms per loop
%timeit any(i in B for i in A) # 102 µs per loop