Python Pandas从另一个数据帧更新数据帧值

时间:2018-04-19 19:05:11

标签: python pandas dataframe

我在python中有两个数据帧。我想使用来自另一个数据帧的匹配值来更新第一个数据帧中的行。第二个数据帧用作覆盖。

以下是具有相同数据和代码的示例:

DataFrame 1:

enter image description here

DataFrame 2:

enter image description here

我想根据匹配的代码和名称更新更新数据帧1。在此示例中,Dataframe 1应更新如下:

enter image description here

注意:Code = 2且Name = Company2的行更新为值1000(来自Dataframe 2)

import pandas as pd

data1 = {
         'Code': [1, 2, 3],
         'Name': ['Company1', 'Company2', 'Company3'],
         'Value': [200, 300, 400],

    }
df1 = pd.DataFrame(data1, columns= ['Code','Name','Value'])

data2 = {
         'Code': [2],
         'Name': ['Company2'],
         'Value': [1000],
    }

df2 = pd.DataFrame(data2, columns= ['Code','Name','Value'])

任何指针或提示?

10 个答案:

答案 0 :(得分:10)

使用DataFrame.update,它对齐索引(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.update.html):

>>> df1.set_index('Code', inplace=True)
>>> df1.update(df2.set_index('Code'))
>>> df1.reset_index()  # to recover the initial structure

   Code      Name   Value
0     1  Company1   200.0
1     2  Company2  1000.0
2     3  Company3   400.0

答案 1 :(得分:8)

您可以使用concat + drop_duplicates

pd.concat([df1,df2]).drop_duplicates(['Code','Name'],keep='last').sort_values('Code')
Out[1280]: 
   Code      Name  Value
0     1  Company1    200
0     2  Company2   1000
2     3  Company3    400

答案 2 :(得分:5)

您可以先合并数据,然后使用numpy.where,here&#39}如何使用numpy.where

updated = df1.merge(df2, how='left', on=['Code', 'Name'], suffixes=('', '_new'))
updated['Value'] = np.where(pd.notnull(updated['Value_new']), updated['Value_new'], updated['Value'])
updated.drop('Value_new', axis=1, inplace=True)

   Code      Name   Value
0     1  Company1   200.0
1     2  Company2  1000.0
2     3  Company3   400.0

答案 3 :(得分:4)

您可以对齐索引,然后使用combine_first

res = df2.set_index(['Code', 'Name'])\
         .combine_first(df1.set_index(['Code', 'Name']))\
         .reset_index()

print(res)

#    Code      Name   Value
# 0     1  Company1   200.0
# 1     2  Company2  1000.0
# 2     3  Company3   400.0

答案 4 :(得分:3)

您可以对左加入df1df2

的结果使用pd.Series.where
merged = df1.merge(df2, on=['Code', 'Name'], how='left')
df1.Value = merged.Value_y.where(~merged.Value_y.isnull(), df1.Value)
>>> df1
    Code    Name    Value
0   1   Company1    200.0
1   2   Company2    1000.0
2   3   Company3    400.0

您可以将线路更改为

df1.Value = merged.Value_y.where(~merged.Value_y.isnull(), df1.Value).astype(int)

以便将值返回为整数。

答案 5 :(得分:2)

假设companycode是冗余标识符,您也可以

import pandas as pd
vdic = pd.Series(df2.Value.values, index=df2.Name).to_dict()

df1.loc[df1.Name.isin(vdic.keys()), 'Value'] = df1.loc[df1.Name.isin(vdic.keys()), 'Name'].map(vdic)

#   Code      Name  Value
#0     1  Company1    200
#1     2  Company2   1000
#2     3  Company3    400

答案 6 :(得分:2)

我经常做某事。

我先合并“左”:

df_merged = pd.merge(df1, df2, how = 'left', on = 'Code')

Pandas将创建扩展名为“ _x”的列(用于您的左侧数据框), '_y'(用于您正确的数据框)

您想要来自右边的那些。因此,只需删除带有“ _x”的所有列并重命名“ _y”即可:

for col in df_merged.columns:
    if '_x' in col:
        df_merged .drop(columns = col, inplace = True)
    if '_y' in col:
        new_name = col.strip('_y')
        df_merged .rename(columns = {col : new_name }, inplace=True)

答案 7 :(得分:1)

  1. 追加数据集
  2. 将副本复制code
  3. 排序值
combined_df = combined_df.append(df2).drop_duplicates(['Code'],keep='last').sort_values('Code')

答案 8 :(得分:1)

以上解决方案均不适用于我的特定示例,我认为它植根于我的列的dtype中,但最终我找到了该解决方案

indexes = df1.loc[df1.Code.isin(df2.Code.values)].index
df1.at[indexes,'Value'] = df2['Value'].values

答案 9 :(得分:1)

有一个更新功能

示例:

df1.update(df2)

有关更多信息:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.update.html