当我在列中已有值时,我在更新数据框时出现问题。
这是一个例子
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
答案 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
创建Name
到ref_df
映射,然后使用它填充数据框中的空白。