python panda Dataframe 中多值行的条件检查和连接

jhkqcmku  于 2023-02-28  发布在  Python
关注(0)|答案(2)|浏览(101)

我有两个 Dataframe ,比如df 1和df 2。df 1有列info,它有来自df 2列code_dig的匹配值。
我想检查df 1的info列是否在df 2的code_dig列中有匹配值,如果有匹配值,则应将相应的code_loc值带入新列。如果同一行中没有用分号分隔的多个值,则非常简单
这是数据的位子集

import pandas as pd
    df1 = pd.DataFrame({'id': [1, 2, 3, 4, 5], 
                       'info': ['301', '521;519', '412;905', '409;206', '301']})

    df2 = pd.DataFrame({'code_dig': [206, 301, 409, 412, 519, 521, 905], 
                       'code_loc': [202, 302, 406, 404.3, 'inf', 'inf', 'inf' ]})

预期产出

id     info added_from_df2
0   1      301            302
1   2  521;519        inf;inf
2   3  412;905      404.3;inf
3   4  409;206        406;202
4   5      301            302

目前为止我所尝试的:由于我无法找到上述问题的解决方案,我尝试了一个变通方案,想到了拆分所有代码并添加相应的代码,然后再次压缩它,这起作用,但问题是代码的顺序很重要。比方说521;519!= 519;521。并且当压缩时,它会打乱原始顺序。

# split all ; seperated codes to assign localised codes
df1['info'] = df1['info'].str.split(';')
df1 = df1.explode('info',ignore_index=True)                           # count: 2227
df_merged = df1.merge(df2, left_on = 'info', right_on = 'code_dig')
grouped = df_merged.groupby('id').agg({'code_dig':'; '.join, 'code_loc':'; '.join,}).reset_index()
# adding localised codes and re-group the splitted signs
digitised_lv = df_merged.merge(grouped, on = 'id', how='inner')
digitised_lv.drop_duplicates(subset = 'id', inplace = True)
# to file
digitised_lv.to_file('result.shp')

一些未完成的尝试包括将DF 2作为字典并尝试ISIN,但它不起作用,或者试图弄清楚两个循环是否可以工作,但由于没有编程背景,我被卡住了。

df1['info']=df1['info'].apply(lambda row: row.split(';'))
new_dict = dict(df2.values)
lst = [new_dict.keys]
df1['info'].isin(lst)

尝试两个循环:

df1['added_from_df2'] = 0
for i, row in df1.iterrows():
    for i_,row_ in df2.iterrows():
        if row['info'] == row_['code_dig']:
            ? HOW to assign :( ?
2guxujil

2guxujil1#

下面是一个复杂变换的选项:

df1.join(
    df1['info']
    .str.split(';')
    .explode()
    .astype(int)
    .map(df2.set_index('code_dig')['code_loc'])
    .astype(str)
    .groupby(level=0).agg(';'.join)
    .rename('added_from_df2')
)

或者使用regex替代方法:

dic = df2.astype(str).set_index('code_dig')['code_loc'].to_dict()
# {'206': '202', '301': '302', '409': '406', '412': '404.3',
#  '519': 'inf', '521': 'inf', '905': 'inf'}

df1['added_from_df2'] = (df1['info']
                         .str.replace('\d+', lambda m: dic.get(m.group(), 'nan'),
                                      regex=True)
                         )

输出:

id     info added_from_df2
0   1      301            302
1   2  521;519        inf;inf
2   3  412;905      404.3;inf
3   4  409;206        406;202
4   5      301            302
2w3kk1z5

2w3kk1z52#

df1.assign(col1=df1["info"].str.split(";")).explode("col1")\
    .astype({"col1":"Int64"}).join(df2.set_index("code_dig"),on="col1")\
    .groupby(["id","info"],as_index=False).agg(added_from_df2=("code_loc",lambda ss:";".join(ss.astype(str))))

输出:

id     info added_from_df2
0   1      301            302
1   2  521;519        inf;inf
2   3  412;905      404.3;inf
3   4  409;206        406;202
4   5      301            302

相关问题