【问题标题】:Merge two Dataframes with different structures合并两个不同结构的数据框
【发布时间】:2021-06-04 14:00:01
【问题描述】:

我正在尝试将两个数据框相互组合。但我被逻辑困住了(也许我对这个问题看得太久了)。

问题: DF1 的格式如下:

Country       ID    March    April  May  June 
Netherlands   A      10       20     15   14 
Netherlands   B      15       18     10    4
Germany       C       9        8      3    1 

然后,我有另一个数据框:

DF2

Country      ID    Month   Number
Netherlands  A     March     8  
Netherlands  A     March     28  
Netherlands  B     April     18  
Germany      C     Jan       9

我想合并这两列(格式与 DF1 相同)。 我的假设是应该是这样的,按(国家+ ID)分组,然后(以月份为列,对数字求和)。 - 但如前所述,我很困惑。

期望的输出:

Country       ID    March    April  May  June   df2_Jan  df2_March   df2_April
Netherlands   A      10       20     15   14       0       36 #8+28     0
Netherlands   B      15       18     10    4       0        0          18
Germany       C       9        8      3    1       9        0           0

希望你能帮助我。提前非常感谢!

【问题讨论】:

标签: python pandas data-wrangling


【解决方案1】:

你可以试试:

merged_df = (
    df1.merge(
        df2.pivot_table(
            index=['Country', 'ID'],
            columns='Month',
            values='Number',
            aggfunc=sum,
            fill_value=0)
        .add_prefix('df2_')
        .reset_index(),
        on=['Country', 'ID']
    )
)

输出:

       Country ID  March  April  May  June  df2_April  df2_Jan  df2_March
0  Netherlands  A     10     20   15    14          0        0         36
1  Netherlands  B     15     18   10     4         18        0          0
2      Germany  C      9      8    3     1          0        9          0

【讨论】:

  • 理想情况下,aggfunc 不应该是np.sum(因为文档的默认值似乎是np.mean)?这也是 pivot_table 文档中的示例所建议的。我不知道为什么,但它们似乎并不完全相同,例如,参见 sum(pd.Series([1, np.nan]))np.sum(pd.Series([1, np.nan]))
  • @Cimbali,我用 0 填充 NaN 值。所以,我想在这种特殊情况下并不重要。
【解决方案2】:
  • 在 DF2 中求和确实是一个简单的groupby().sum() 操作

    df2 = df2.groupby(['Country', 'ID', 'Month'])['Number'].sum()
    

    您现在有一个具有 3 级索引的系列。

  • 似乎使 DF2 的格式与 DF1 相同,您只需要一个 .unstack() 即可将其中一个索引级别转换为列。

    df2 = df2.unstack('Month', fill_value=0)
    
  • 现在可以轻松合并相同格式

    df1.merge(df2.add_prefix('df2_').reset_index(), on=['Country', 'ID'])
    

根据@Nk03 的回答,可以使用aggfunc 参数调用.pivot_table 来替换第1 步和第2 步。

【讨论】:

  • 感谢您的帮助!正在检查答案,但 unstack 部分无法正常工作“KeyError: 'Level Number not found'
  • @Roverflow 确实与Month 无关。它只是将索引级别移动到列,因此您可以适当地使用所需级别的名称。
猜你喜欢
  • 2019-12-16
  • 2022-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 2013-03-24
  • 2014-03-30
  • 1970-01-01
  • 2016-08-15
相关资源
最近更新 更多