gpt4 book ai didi

python - 与通配符合并

转载 作者:太空宇宙 更新时间:2023-11-04 09:56:54 25 4
gpt4 key购买 nike

我正在尝试使用带有通配符的多列合并两个 pandas 数据框。

考虑数据集,其中结果是所需合并的结果:

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]})
result=pd.DataFrame({'Type':['ABC','ADEC','OOO','DOG','MOT'], 'ID':[22,44,23,21,55],'Value': [0,1,1,0,'NaN']})

给出:

left
ID Type
0 22 ABC
1 44 ADEC
2 23 OOO
3 21 DOG
4 55 MOT

right
ID Type Value
0 22 ABC 0
1 * ADE* 1
2 23 * 1
3 2* DOG 0

result
ID Type Value
0 22 ABC 0
1 44 ADEC 1
2 23 OOO 1
3 21 DOG 0
4 55 MOT NaN

我尝试使用:

pd.merge(left=left, right=right, left_on=['Type', 'ID'], right_on ['Type','ID'], how='left')

但结果是:

pd.merge(left=left, right=right, left_on=['Type', 'ID'], right_on= ['Type','ID'], how='left')
ID Type Value
0 22 ABC 0.0
1 44 ADEC NaN
2 23 OOO NaN
3 21 DOG NaN
4 55 MOT NaN

非常感谢任何帮助。谢谢!

最佳答案

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

此 DataFrame 显示 right 的每一行left['ID'] 中的值是什么匹配模式。例如,在最后一行中,模式是 2.匹配 22 , 2321left['ID'] .

如果我们 stack这个DataFrame,我们得到一个Series,列出所有可能的通配符扩展:

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 也可以这样做.将两个结果连接在一起以获得一个 DataFrame,其中列出了通配符的每个有效扩展:

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:我修改了rightindex=list('ABCD')而不是通常的 [0,1,2,3]这样 left 上的索引值和 right不要碰巧与我们希望行匹配的方式对齐。我这样做是为了防止开发错误地利用这个的解决方案巧合。

关于python - 与通配符合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45442867/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com