【问题标题】:Using Pandas, how can you match from multiple indexes in a series, match to a DataFrame and replace multiple columns使用 Pandas,如何从系列中的多个索引匹配、匹配到 DataFrame 并替换多个列
【发布时间】:2020-11-23 18:56:02
【问题描述】:

我正在尝试将一个数据框中的值组合与另一个数据框中的相同组合(本质上是一个查找表)进行匹配。如果我在查找表中找到匹配项,请从查找中替换原始值。我尝试过使用replace、map、loc,但我觉得我更困惑了。

我有一个示例数据框,

example1 = {
    'Code': ['99233','99233','99233','90732','93306','93306','93306'],
    'Modifier': ['','','','','','TC','26'],
    'W': ['0','0','0','0','0','0','0'],
    'P': ['0','0','0','0','0','0','0'],
    'M': ['0','0','0','0','0','0','0']
}
df1 = pd.DataFrame(example1)

看起来像这样,

    Code    Modifier    W   P   M
0   99233               0   0   0
1   99233               0   0   0
2   99233               0   0   0
3   90732               0   0   0
4   93306               0   0   0
5   93306   TC          0   0   0
6   93306   26          0   0   0

然后我会使用如下查找表...

example2 = {
    'Code': ['99233','90732','93306','93306','93306'],
    'Modifier': ['','','','TC','26'],
    'W': ['2','0','1.5','0','1.5'],
    'P': ['0.81','0','4.29','3.76','0.53'],
    'M': ['0.13','0','0.7','0.2','0.05']
}
df2 = pd.DataFrame(example2)

看起来像这样,

    Code    Modifier    W   P       M
0   99233               2   0.81    0.13
1   90732               0   0       0
2   93306               1.5 4.29    0.7
3   93306   TC          0   3.76    0.2
4   93306   26          1.5 0.53    0.05

我希望能够使用“代码”和“修改器”字段并替换主数据框 (df1) 中 W、P 和 M 的值。

通过将查找表转换为系列(我不确定这是否正确但有意义)并使用字典中的代码作为我的索引,我能够匹配一个值

vdic = pd.Series(df2.W.values, index=df2.Code).to_dict()
df1.loc[df1.Code.isin(vdic.keys()), 'W'] = df1.loc[(df1.Code.isin(vdic.keys())), 'Code'].map(vdic)
df1

这让我在第一列中走到了一半,但显然没有接受修饰符。

    Code    Modifier    W   P   M
0   99233               2   0   0
1   99233               2   0   0
2   99233               2   0   0
3   90732               0   0   0
4   93306               1.5 0   0
5   93306   TC          1.5 0   0
6   93306   26          1.5 0   0

我尝试在字典中添加第二个索引,

vdic = pd.Series(df2.W.values, index=[df2.Code, df2.Modifier]).to_dict()

{('99233', ''): '2',
 ('90732', ''): '0',
 ('93306', ''): '1.5',
 ('93306', 'TC'): '0',
 ('93306', '26'): '1.5'}

我认为这会奏效,但我必须让它变得比实际更复杂,而且到目前为止的每一次尝试都没有奏效。我检查了其他线程,代码到处都是。

任何帮助或建议将不胜感激。

我也很好奇我是否可以一次更新所有三列(W、P 和 M),还是应该细分?

从@user13802115 的第一个答案编辑(顺便说一句,这很棒)

我应该修改问题并询问当数据框大小不同时是否可以执行相同的操作。

example3 = {
    'Other1': ['1','7','4','54','9','43','22'],
    'Other2': ['A','Z','Y','BB','7W','9','Left'],
    'Code': ['99233','99233','99233','90732','93306','93306','93306'],
    'Modifier': ['','','','','','TC','26'],
    'W': ['0','0','0','0','0','0','0'],
    'P': ['0','0','0','0','0','0','0'],
    'M': ['0','0','0','0','0','0','0']
}
df3 = pd.DataFrame(example3)

基本上就地编辑,只更新第一个数据框中查找表中的值,而其他项目保持不变。

下面的解决方案

感谢@user13802115 的回答,我使用了以下链接: Pandas merging on different size dataframes based on one column

得到我需要的东西。使用修改后的数据框 (df3),我可以运行以下命令来合并我的数据,将附加的值拖放到我的初始数据框中,然后重新索引,以便所有内容都保持最初创建的状态,并带有更新的字段。

df = (df3.merge(df2, on=['Code','Modifier'], how='left', suffixes=('_',''))
        .drop(['W_','P_','M_'], axis=1)
        .reindex(columns=df1.columns))
df

【问题讨论】:

    标签: python pandas dataframe multi-index


    【解决方案1】:

    我不太确定,但我相信这就是你想要的。

    df3 = pd.merge(df1[['Code','Modifier']],df2,on = ['Code','Modifier'],how = 'left').fillna('0')
    

    【讨论】:

    • 好的,这很棒,但有一个问题,如果第一个数据框有更多列怎么办?
    • 回答了我自己的问题并放在上面。感谢您的帮助!!!
    【解决方案2】:

    我认为这就是你想要做的:

    for code_ind, code in enumerate(df1.Code.unique()):
        modifiers = df1.loc[df1['Code']==code].Modifier.unique()
        for mod_ind, modifier in enumerate(modifiers):
            row_to_modify = df1.loc[(df1['Code']==code) &(df1['Modifier']==modifier)].iloc[0].name
            lookup_row = df2.loc[(df2['Code']==code) & (df2['Modifier']==modifier),['W','P','M']].iloc[0].name
            df1.loc[df1.index[row_to_modify],['W','P','M']] =  df2.loc[df2.index[lookup_row],['W','P','M']]
    

    这仅使用查找表中每个代码的第一个索引修改基表中每个代码的第一次出现。但是,它不会将不存在的值附加到基表中,我不确定您是否想要。

    这是使用您提供的字典的示例输出数据框:

        Code Modifier    W     P     M
    0  99233             2  0.81  0.13
    1  99233             0     0     0
    2  99233             0     0     0
    3  90732             0     0     0
    4  93306           1.5  4.29   0.7
    5  93306       TC    0  3.76   0.2
    6  93306       26  1.5  0.53  0.05
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-08
      • 2016-10-23
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多