import pandas as pd
left = pd.DataFrame(
{'Type': ['ABC', 'ADEC', 'OOO', 'DOG', 'MOT'], 'ID': [22, 44, 23, 21, 55]})
right = pd.DataFrame({'Type': ['ABC', 'ADE*', '*', 'DOG'],
'ID': [22, '*', '23', '2*'], 'Value': [0, 1, 1, 0]},
index=list('ABCD'))
expected = pd.DataFrame({'Type': ['ABC', 'ADEC', 'OOO', 'DOG', 'MOT'], 'ID': [
22, 44, 23, 21, 55], 'Value': [0, 1, 1, 0, 'NaN']})
data = {}
for col in ['ID', 'Type']:
right[col] = right[col].astype(str).str.replace('*','.')
left[col] = left[col].astype(str)
data[col] = (right[col].apply(lambda pat: left.loc[left[col].str.match(pat), col])
.stack().to_frame(col))
data[col].index = data[col].index.droplevel(level=1)
expanded = (data['ID']
.join(data['Type'])
.join(right['Value']))
result = pd.merge(left, expanded, how='left')
print(result)
产生
ID Type Value
0 22 ABC 0.0
1 44 ADEC 1.0
2 23 OOO 1.0
3 21 DOG 0.0
4 55 MOT NaN
如果更改*
到.
,你可以把在right
的值作为正则表达式模式。 然后,您可以使用str.match(pat)
来测试right
中的模式是否与left
中的字符串匹配。例如,
In [297]: right
Out[297]:
ID Type Value
A 22 ABC 0
B . ADE. 1
C 23 . 1
D 2. DOG 0
In [298]: left
Out[298]:
ID Type
0 22 ABC
1 44 ADEC
2 23 OOO
3 21 DOG
4 55 MOT
In [271]: right['ID'].apply(lambda pat: left.loc[left['ID'].str.match(pat), 'ID'])
Out[271]:
0 1 2 3 4
A 22 NaN NaN NaN NaN
B 22 44 23 21 55
C NaN NaN 23 NaN NaN
D 22 NaN 23 21 NaN
此数据框显示的right
每一行什么left['ID']
值相匹配的模式。例如,在最后一行中,模式为2.
,其与left['ID']
中的22
,23
和21
相匹配。
如果我们stack
这个数据帧,我们得到了一个系列上市通配符的所有可能的扩展:
In [299]: right['ID'].apply(lambda pat: left.loc[left['ID'].str.match(pat), 'ID']).stack()
Out[299]:
A 0 22
B 0 22
1 44
2 23
3 21
4 55
C 2 23
D 0 22
2 23
3 21
dtype: object
同样可以为Type
来完成。将两个结果结合在一起,以获得一个数据帧,它列出了通配符的每一个有效的扩展:
In [301]: expanded = (data['ID']
.join(data['Type'])
.join(right['Value']))
Out[301]:
ID Type Value
A 22 ABC 0
B 22 ADEC 1
B 44 ADEC 1
B 23 ADEC 1
B 21 ADEC 1
B 55 ADEC 1
C 23 ABC 1
C 23 ADEC 1
C 23 OOO 1
C 23 DOG 1
C 23 MOT 1
D 22 DOG 0
D 23 DOG 0
D 21 DOG 0
现在所希望的结果可以通过left
和expanded
左合并来获得:
result = pd.merge(left, expanded, how='left')
PS:我改变right
有index=list('ABCD')
而不是通常的 [0,1,2,3]
,以便对left
和索引值不会发生在 与我们希望行匹配的方式一致。我这样做是为了防范开发一种错误地利用这种巧合的解决方案。
我不认为熊猫有合并,联合等使用通配符的功能...... –