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
和索引值不會發生在 與我們希望行匹配的方式一致。我這樣做是爲了防範開發一種錯誤地利用這種巧合的解決方案。
我不認爲熊貓有合併,聯合等使用通配符的功能...... –