【问题标题】:Mapping values to dataframe from a different dataframe in Pandas将值从 Pandas 中的不同数据帧映射到数据帧
【发布时间】:2017-04-06 06:07:54
【问题描述】:

问题:我有 2 个数据框 df1df2。我的目标是修改df1,如果在df2 中找到它的一些值,则替换它。

import pandas as pd

# dataframe 1
data = {'A':[90,20,30,25,50,60],
        'B':['qq','ee','rr','tt','ii','oo'],
        'C':['XX','VV','BB','NN','KK','JJ']}
df1 = pd.DataFrame(data)

# dataframe 2
convert_table = {'X': ['dd','ee','ff','gg','hh','ii','ll','mm','nn','oo','pp','qq','rr','ss','tt','uu'], 
                 'Y': ['DD','VV','FF','GG','HH','KK','LL','MM','NN','JJ','PP','XX','BB','SS','NN','LL'], 
                 'Z': [5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61]}
df2 = pd.DataFrame(convert_table)

# search values of df1 inside of df2 and replace values
for idx1,row1 in df1.iterrows():
    for idx2, row2 in df2.iterrows():
        if row1['B']==row2['X'] and row1['C']==row2['Y']:
            df1.replace(to_replace=row1['B'],value=row2['Z'],inplace=True) 

如您所见,我有 2 个 for 循环,我检查是否在 df2 内找到了 df1 (row1) 的通用行。如果满足此条件,则将 row1['B'] 中包含的值替换为 row2['Z'] 中包含的值

因此我得到的结果是(正是我想要的结果):

In [120]: df1
Out[120]: 
    A   B   C
0  90  43  XX
1  20   7  VV
2  30  47  BB
3  25  59  NN
4  50  19  KK
5  60  37  JJ

注意 B 列的变化。

问题:您能给我推荐一个更好的方法来编写我的代码吗?我想尽可能快地使用 Pandas 或 Python 提供的内置函数。

注意:数据框中包含的数据仅用于演示目的。

【问题讨论】:

    标签: python pandas dataframe replace mapping


    【解决方案1】:

    在两列上使用合并:

    df1.merge(df2, left_on=['B','C'], right_on=['X','Y'], how='left')
    

    how='left' 在这里很重要。如果您不明白原因,请阅读Brief primer on merge methods (relational algebra)

    我将修改您的示例以创建一个在 df1 中有一个在 df2 中不存在的条目,即 ('ii','KK')

    In [1]:
    # dataframe 2
    convert_table = {'X': ['dd','ee','ff','gg','hh','ll','mm','nn','oo','pp','qq','rr','ss','tt','uu'], 
                     'Y': ['DD','VV','FF','GG','HH','LL','MM','NN','JJ','PP','XX','BB','SS','NN','LL'], 
                     'Z': [5,7,11,13,17,19,23,29,37,41,43,47,53,59,61]}
    df2 = pd.DataFrame(convert_table)
    
    
    
    In [2]: merged = df1.merge(df2, left_on=['B','C'], right_on=['X','Y'], how='left')
            merged
    Out[2]: 
        A   B   C    X    Y     Z
    0  90  qq  XX   qq   XX  43.0
    1  20  ee  VV   ee   VV   7.0
    2  30  rr  BB   rr   BB  47.0
    3  25  tt  NN   tt   NN  59.0
    4  50  ii  KK  NaN  NaN   NaN
    5  60  oo  JJ   oo   JJ  37.0
    

    现在检索最终的数据帧:

    In [3]:
    merged.ix[merged.Z.notnull(),'B'] = merged.ix[merged.Z.notnull(),'Z']
    merged = merged[['A','B','C']]
    merged
    
    Out[3]:
        A   B   C
    0  90  43  XX
    1  20   7  VV
    2  30  47  BB
    3  25  59  NN
    4  50  ii  KK
    5  60  37  JJ
    

    【讨论】:

    • 是否可以获得与我在示例中得到的列数相同的输出?
    • 我刚刚在您发表评论的同时这样做了 :)
    猜你喜欢
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多