【问题标题】:Emulating an excel sumifs / multi-criteria index match with dataframes in python / pandas在 python / pandas 中模拟与数据帧匹配的 excel sumifs / 多标准索引
【发布时间】:2018-01-23 20:12:07
【问题描述】:

我在 python 中有两个使用 pandas 的数据框:

  • df1: [233,500 x 6] 按日期分类的价格
  • df2:[1,665,997 x 5] 按日期划分的客户使用分类帐

在 excel 中较小的数据集上,我可以简单地执行以下操作,在 df2 上创建一列,按行包含给定日期的每种产品价格。

=SUMIFS(df1[Rate],df1[Date],[@Date],df1[Jurisdiction],[@Jurisdiction],df1[Product],[@Product])

最终我想在 df2 中添加一列(或使用结果创建一个新的数据框),通过匹配每行中的某些条件(司法管辖区、产品类型)中的相同条件来提供价格价格分类帐 df1。

使用 python 和数据框关联这些数据的最合适方法是什么?某种字典和连接?

我发现的例子主要是在某些条件下处理求和:

奖励:df1 和 df2 中的日期并不总是完全相同。需要将 df2 中的日期与最近的价格分类帐日期匹配。

编辑:我在下面包含了简化数据,以演示我如何尝试进行最近的日期匹配。日期匹配只是在 df2 中查找每个日期的有效价格的中间步骤。两个日期列上的直接合并不起作用,因为不是每天都提供价格。

df1:
Date       Price
1/11/2016  5.00
1/12/2016  5.50
1/13/2016  6.00
1/14/2016  7.00
1/16/2016  8.00
1/20/2016  9.00
1/21/2016  10.00
1/22/2016  11.00

df2:
Date       Volume
1/11/2016  100
1/15/2016  100
1/17/2016  200
1/18/2016  300
1/20/2016  200

df3: (df2 with date matching. Cost = Volume*Price)
Date       Volume  MatchedDate  Price  Cost
1/11/2016  100     1/11/2016    5.00   500
1/15/2016  100     1/14/2016    7.00   700
1/17/2016  200     1/16/2016    8.00   1600
1/18/2016  300     1/16/2016    8.00   2400
1/20/2016  200     1/20/2016    9.00   1800

编辑 2:以下第一部分中提供的公式在 excel 中有效,具有一些额外的逻辑,用于在第一个 df1 条目之前使用 df2 条目的第一个日期。 https://www.extendoffice.com/documents/excel/2601-excel-find-closest-date.html

{=MAX((df1[Date]<[@Date])*df1[Date])}

【问题讨论】:

  • 如果你能分享一个你的数据框和你期待的结果的小例子,那就太好了。

标签: python excel pandas dataframe sumifs


【解决方案1】:

只需根据匹配条件合并两组,然后运行groupby sum:

merged_df = pd.merge(df1, df2, on=['date', 'Jurisdiction', 'Product'])

merged_df.groupby(['date', 'Jurisdiction', 'Product'])['Rate'].sum()

或者最近的日期为df2

most_recent_df2 = df2.merge(df2.groupby(['Jurisdiction', 'Product'])['date'].max().reset_index(), 
                            on=['date', 'Jurisdiction', 'Product'])

merged_df = pd.merge(df1, most_recent_df2, on=['Jurisdiction', 'Product'], suffixes=['', '_'])

merged_df.groupby(['date', 'Jurisdiction', 'Product'])['Rate'].sum()

【讨论】:

  • 这非常有效。我之前尝试过合并功能,但遇到了 MemoryErrors。不知道这里有什么区别,但它有效。谢谢先生。
  • 我已经编辑了 OP,其中包含有关日期匹配的更多详细信息。以下是大约 99%,但使用数据框列存在歧义错误。 stackoverflow.com/questions/32237862/…
  • 您可能需要提出一个新问题,因为这偏离了具有 JurisdictionProduct 标准的 SUMIF。并查看merge_asof
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多