【问题标题】:Python Pandas fill missing column with left joinPython Pandas 用左连接填充缺失的列
【发布时间】:2021-03-25 12:49:41
【问题描述】:

我有以下两个数据框。

df_1

AA BB CC DD
"Apple" XYZ1 XYZ2
"Apple" PQR1 PQR2
"Apple" XYZ4 PRR9
"Banana" XYZ1 416
"Banana" XYZ1 416
"Apple" XYZ4 PRR9

df_lookup

AA XX YY ZZ
"Apple" XYZ1 XYZ2 429
"Apple" XYZ4 PRR9 97
"Apple" PQR1 PQR2 108
"Banana" XYZ1 PQR1 416

预期结果:

我的目标是填写 df_1 中的空值。换句话说:

if AA == "Apple" then 
 df_1.DD = SELECT df_lookup.ZZ 
 FROM df_lookup 
 LFET JOIN df_1 
 ON df_1.BB = df_lookup.XX, df_1.CC = df_lookup.YY

恰恰相反……

if AA == "Banana" then 
 df_1.CC = SELECT df_lookup.YY 
 FROM df_lookup 
 LFET JOIN df_1 
 ON df_1.BB = df_lookup.XX, df_1.DD = df_lookup.ZZ

df_1(填充/修改)

AA BB CC DD
"Apple" XYZ1 XYZ2 429
"Apple" PQR1 PQR2 108
"Apple" XYZ4 PRR9 97
"Banana" XYZ1 PQR1 416
"Banana" XYZ1 PQR1 416
"Apple" XYZ4 PRR9 97

到目前为止,我尝试了以下方法

apple_merged = pd.merged(df_1, df_lookup, left_on = ["BB", "CC"], right_on = ["XX", "YY"])
df_1[(df_1["AA"] == "Apple")]["DD"] = apple_merged[(apple_merged.AA == "Apple")]["ZZ"].values

我的实际代码中出现以下错误:

ValueError:值的长度 (501) 与索引的长度不匹配 (602)

这似乎表明数据的形状在分配的另一侧是不同的,501 v/s 602。但是如果我真的做了左连接,在这种情况下,行数对我来说是否不一样?

【问题讨论】:

  • 您期望最终结果是什么样子的?
  • 请发布您的预期输出。
  • @piRSquared & Mayank :除了查询之外,还添加了预期结果 DataFrame 示例。谢谢!

标签: python pandas dataframe python-3.8


【解决方案1】:

当您在 pandas 中合并两个数据框时,您必须传递一个 how = 参数,否则 pandas 默认为内连接。然后导致错误,因为您的内部连接 ​​apple_merged 数据帧中有 501 个值,df_1 中有 602 个值。

链接:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.merge.html

【讨论】:

    【解决方案2】:

    首先使用merge() 方法,所以这里我们使用默认值,即内部连接:-

    df=df_1.merge(df_lookup,how='left',left_on=['AA','BB'],right_on=['AA','XX'])
    

    现在使用fillna()方法在'YY'和'ZZ'的基础上填充'DD'和'CC'的值:-

    df['DD']=df['DD'].fillna(df['ZZ']).astype(int)
    df['CC']=df['CC'].fillna(df['YY'])
    

    现在您的所有值都已填充,因此我们必须通过drop() 方法删除额外的列并将列参数传递给列表:-

    df=df.drop(columns=['XX','YY','ZZ'])
    

    现在,如果您打印 df,您将获得预期的输出:-

        AA       BB     CC      DD
    0   Apple   XYZ1    XYZ2    429
    1   Apple   PQR1    PQR2    108
    2   Apple   XYZ4    PRR9    97
    3   Banana  XYZ1    PQR1    416
    4   Banana  XYZ1    PQR1    416
    5   Apple   XYZ4    PRR9    97
    

    编辑:如果 df_lookup 没有 AA 列,

    df=df_1.merge(df_lookup,left_on=['BB'],right_on=['XX'])
    df['DD']=df['DD'].fillna(df['ZZ']).astype(int)
    df['CC']=df['CC'].fillna(df['YY'])
    df=df.drop(columns=['XX','YY','ZZ'])
    

    如果您想删除重复项,请使用:-

    df=df.drop_duplicates()
    

    【讨论】:

    • 除了查询之外,还添加了预期结果 DataFrame 示例。谢谢!
    • 谢谢!我会看看。如果 df_lookup 没有 AA 列,您会做哪些更改?
    • 根据您的查询更新了我的答案....请看一下
    【解决方案3】:

    用途:

    d = {'XX':'BB','YY':'CC', 'ZZ':'DD'}
    
    #column for rename
    df2 = df_lookup.rename(columns=d)
    #left join by defined columns
    df = (df_1.merge(df2, how='left', on=['AA','BB','CC'], suffixes=('','_'))
              .merge(df2, how='left', on=['AA','BB','DD'], suffixes=('','_')))
    
    #replaced original columns by added columns with _
    cols = df.columns[df.columns.str.endswith('_')]
    df = df.combine_first(df[cols].rename(columns=lambda x: x.strip('_'))).drop(cols, axis=1)
    print (df)
           AA    BB    CC     DD
    0   Apple  XYZ1  XYZ2  429.0
    1   Apple  PQR1  PQR2  108.0
    2   Apple  XYZ4  PRR9   97.0
    3  Banana  XYZ1  PQR1  416.0
    4  Banana  XYZ1  PQR1  416.0
    5   Apple  XYZ4  PRR9   97.0
    

    【讨论】:

    • 我很好奇...如果df_lookup 没有AA 列,你会做出什么改变?
    猜你喜欢
    • 2015-07-25
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2021-08-25
    • 2020-02-28
    • 1970-01-01
    • 2022-11-02
    • 2017-05-08
    相关资源
    最近更新 更多