Python Pandas - 使用另一个的值更新数据框,而不替换现有的

时间:2018-02-09 16:56:46

标签: python pandas dataframe

当我在列中已有值时,我在更新数据框时出现问题。

这是一个例子

import pandas as pd
df = pd.DataFrame({
                  'email':['1@dummy.com','2@dummy.com','3@dummy.com','4@dummy.com'],
                  'Name': ['John', 'Sam',None,None],
                  'id': ['A0', 'A1','A2', 'A3'], }
                     )
df

    df
        Name    email   id
    0   John    1@dummy.com A0
    1   Sam     2@dummy.com A1
    2   None    3@dummy.com A2
    3   None    4@dummy.com A3

ref_df = pd.DataFrame({
                  'email':['1@dummy.com','2@dummy.com','3@dummy.com','4@dummy.com'],
                  'Name': ['', 'Sam','Tim','Sara'],
                  'random': ['f', 's','r', 'a'], }
                     )
ref_df
Name           email      random
0           1@dummy.com     f
1   Sam     2@dummy.com     s
2   Tim     3@dummy.com     r
3   Sara    4@dummy.com     a

我想要的结果如下:

Name           email    id
0   John    1@dummy.com A0
1   Sam     2@dummy.com A1
2   Tim     3@dummy.com A2
3   Sara    4@dummy.com A3

我想根据Name使用ref_df中的值填充email,但保留现有值。仅更新name中的空值。也只保留df中的原始列(去掉ref_df中的随机列)

我也希望能够重复这样做,因为我想用不同来源的多个ref_df更新df。

下面是我尝试的,如果我逐行运行代码,这是有效的,但是一旦我将它包装在一个函数中,我就得到了一个keyerror。

我确信有更好的方法可以做到这一点。任何帮助表示赞赏!

def update_df(df, index, ref_df, ref_cols,how='inner',left_on=None,
              right_on=None,):
    df = init_columns(df, cols=ref_cols)
    cols_to_keep = list(df.columns)
    gap_cols = df.columns.difference(ref_df.columns)
    gap_df = merge(
        df[gap_cols],
        ref_df,
        how,
        left_on,
        right_on,
    )
    gap_df = gap_df[cols_to_keep].set_index(index)
    df = df.set_index(index)
    df.update(gap_df)
    df=df[cols_to_keep]
    return df

2 个答案:

答案 0 :(得分:1)

我所做的是将您的ref_df转换为字典,以便我们可以应用映射。

ref_dict = dict(zip(ref_df["email"], ref_df["Name"]))
ref_dict

这会给你:

{'1@dummy.com': 'John',
 '2@dummy.com': 'Sam',
 '3@dummy.com': 'Tim',
 '4@dummy.com': 'Sara'}

然后,你可以:

df["Name"] = df["email"].map(ref_dict)

你将拥有:

    Name          email id
0   John    1@dummy.com A0
1   Sam     2@dummy.com A1
2   Tim     3@dummy.com A2
3   Sara    4@dummy.com A3

这将重新创建Name列,如果您担心这可能会更改某些现有值,则只能填充NA列。{/ p>

答案 1 :(得分:0)

这应该有效:

df['Name'] = df['Name'].fillna(df['email'].map(ref_df.set_index('email')['Name']))

此方法的工作方式是从email创建Nameref_df映射,然后使用它填充数据框中的空白。