【问题标题】:Merge dataframes of different sizes and simultaneously overwrite NaN values合并不同大小的数据帧并同时覆盖 NaN 值
【发布时间】:2019-08-29 23:54:37
【问题描述】:

我想在 Python 中组合两个不同大小的数据框。这些数据框是从 Excel 文件中加载的。第一个数据帧有许多包含 NaN 的空值,第二个数据帧有数据来替换第一个数据帧中的 NaN 值。这两个数据框由第一列中的数据链接,但顺序不同。

我可以使用 merge() 成功合并和组织数据帧,但生成的数据帧有额外的列,因为 NaN 值没有被覆盖。我可以用 fillna() 覆盖 NaN 值,但生成的数据帧是乱序的。有没有办法执行这种替换 NaN 的合并,而不需要单独的删除和重新排序列的操作?

import pandas as pd
import numpy as np

df1=pd.DataFrame({'A':[1,2,3],'B':[np.nan,np.nan,np.nan],'C':['X','Y','Z']})
df1
   A   B  C
0  1 NaN  X
1  2 NaN  Y
2  3 NaN  Z
df2=pd.DataFrame({'A':[3,1,2],'B':['U','V','W'],'D':[7,8,9]})
df2
   A  B  D
0  3  U  7
1  1  V  8
2  2  W  9

如果我这样做:

df1.merge(df2,how='left',on='A',sort=True)
   A  B_x  C B_y  D
0  1  NaN  X   V  8
1  2  NaN  Y   W  9
2  3  NaN  Z   U  7

数据是有序的,但 B 有多个实例。 如果我这样做:

df1.fillna(df2)
   A  B  C
0  1  U  X
1  2  V  Y
2  3  W  Z

数据乱序,但是替换了NaN。

我希望输出是一个如下所示的数据框:

df3
   A  B  C  D
0  1  V  X  8
1  2  W  Y  9
2  3  U  Z  7

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    你可以使用:

    df3=pd.concat([df1['C'],df2[['A','B','D']].sort_values('A').reset_index(drop=True)],axis=1).reindex(columns=['A','B','C','D'])
    

    输出:

    df3
    

        A   B   C   D
    0   1   V   X   8
    1   2   W   Y   9
    2   3   U   Z   7
    

    说明:

    sort_valuesdf2根据列A下单。

    reset_index (drop = True) 是按正确顺序连接DataFrame 所必需的。

    我使用concatdf1 'C'df2 加入到columns 的列中,columns 现在的顺序正确。最后我使用reindex 重新定位DataFrame df3columns

    可以看到DataFramedf2的顺序没有改变,因为我们没有使用inplace = True

    【讨论】:

    • 这里的逻辑存在缺陷。请注意,在输出中,虽然 B 列现在正确映射到 A 列,但 C 列没有组织。
    • 对不起,我解决问题并上传代码!,如果您有任何问题,请随时提问。
    • 优雅!我喜欢!
    • 谢谢。您对代码还有其他问题吗?
    • 不,这是有道理的。
    【解决方案2】:
    d = dict(zip(df2.A,df2.B))
    df1["B"] = df1["A"].map(d)
    del df2["B"]
    df1.merge(df2,how='left',on='A',sort=True)
    

    【讨论】:

    • 为什么 OP 应该“试试这个”?解释您的建议/答案通常被认为是一种很好的形式。仅代码的答案可能会令人惊讶地缺乏信息,即使它们在技术上是正确的。 好的答案将始终解释所做的事情以及这样做的原因,不仅适用于 OP,而且适用于可能会发现此问题并正在阅读您的答案的 SO 的未来访问者。
    • 此代码似乎有效。但是,我正在使用具有许多 NaN 列的较大数据框。有没有办法将映射概括为多个列,还是我必须单独进行? df1[2:3]=df1['A'].map(d) 抛出关于键长度的错误。
    • df1[2:3] 将切片行(在本例中为第三行)而不是列。假设 df1 有另一个由 NaN 组成的“D”列,那么 df1[["B","D"]] = mapping 需要映射到形状与df1[["B","D"]] 相同,即你不能df1[["B","D"]] = df1["A"].map(d)
    猜你喜欢
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 2012-12-15
    相关资源
    最近更新 更多