【问题标题】:Replicate rows to prepare Pandas DataFrame for date-based merge复制行以准备 Pandas DataFrame 以进行基于日期的合并
【发布时间】:2017-04-25 20:38:14
【问题描述】:

我有一个带有几百万行项目/组的 pandas df,名为 items

Item  Group
0001  A
0002  A
0003  B
0004  A
...

我需要准备 items 与一个名为 forecast 的 df 合并,如下所示:

Item  Group  Month Forecast
0001  A      5     15
0001  A      6     16
0001  A      7     13
0002  A      5     60
0002  A      7     65

我的合并看起来像: items.merge(forecast, on=['Item', 'Group', 'Month']

所以我的问题是准备items 看起来像这样:

Item  Group  Month
0001  A      5
0001  A      6
0001  A      7
0002  A      5
0002  A      6
0002  A      7
...

因此对于给定的一组月份(例如 5, 6, 7),每个项目/组组合都有 len(months) 行,无论是否有预测 forecast 中该项目/组/月的数据

需要保留顺序(例如,给定项目/行的三个月需要组合在一起,而不是仅附加到末尾的副本,并且项目需要保持顺序)。

到目前为止,我一直在研究 stack() 作为一个可能的选项,但我还没有得到任何工作(除了循环遍历 df,将行 * 2 附加到一个新的空 df 中,这似乎非常低效)。

这样做的正确方法是什么?

【问题讨论】:

  • 合并将包含哪些新信息?没有预测的项目/组/月的 NaN?
  • @Charlie 是的。但我已经简化了数据框。 itemsforecast 也有其他列,所以真正的目标是将来自 forecast 的“预测”信息带入 items 并为所有缺失的预测创建 NaN。此外,itemsforecasts 的超集,因此直接在 forecast 上执行操作不会为所有项目创建它。

标签: python pandas dataframe merge


【解决方案1】:
months = [5, 6, 7]

idx = items.index.repeat(len(months))
months_ = months * len(items)
items_ = items.loc[idx].assign(Month=months_).reset_index(drop=True)

print(items_)

    Item Group  Month
0      1     A      5
1      1     A      6
2      1     A      7
3      2     A      5
4      2     A      6
5      2     A      7
6      3     B      5
7      3     B      6
8      3     B      7
9      4     A      5
10     4     A      6
11     4     A      7

forecast.merge(items_)

   Item Group  Month  Forecast
0     1     A      5        15
1     1     A      6        16
2     1     A      7        13
3     2     A      5        60
4     2     A      7        65

【讨论】:

  • 这是我想象中的巧妙 pandas-ee 答案!我想我会坚持使用另一个,尽管它可能效率较低,但 b/c 它更明确地说明了正在发生的事情。
  • @SeanKramer 那是你的选择(当然)......希望这仍然有用:-)
  • 当然有用! repeat 和 assign 函数都是我以前没有遇到过的,我可能已经用过很多次了。
【解决方案2】:

从以下数据框开始,列项和组未设置为索引,我有以下内容:

   Item Group
0  0001     A
1  0002     A
2  0003     B
3  0004     A

items_mod = pd.DataFrame()
for i in [5, 6, 7]:
    items['Month'] = i
    items_mod = items_mod.append(items)
items_mod = items_mod.sort_values('Item')

这给了我以下数据框:

   Item Group  Month
0  0001     A      5
0  0001     A      6
0  0001     A      7
1  0002     A      5
1  0002     A      6
1  0002     A      7
2  0003     B      5
2  0003     B      6
2  0003     B      7
3  0004     A      5
3  0004     A      6
3  0004     A      7

【讨论】:

  • 这基本上是我最终的结果。唯一的问题是它不保留项目的原始顺序(它们实际上在真实 DF 中不是按排序顺序排列的)。为了解决这个问题,我只是将索引保留为一列,然后对其进行排序。不知道为什么我认为它比这更复杂。
【解决方案3】:

尝试外部合并

pd.merge(items, forecast, on=['Item', 'Group'], how='outer')

From here

如果没有,请尝试此页面以获得更多灵感:http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

【讨论】:

  • 这不涉及在items 中创建一个合理的“月份”列,其中包括所有个可能的项目/组/月份组合。这是这里的问题,而不是完成后如何合并。
  • 如果我做得正确,应该在合并中添加几个月......我想。我更新了答案以删除 'Month' 键。转到链接中的外部合并,看看是否可以满足您的要求。
猜你喜欢
  • 1970-01-01
  • 2019-07-12
  • 2019-01-10
  • 2015-07-19
  • 2018-11-05
  • 1970-01-01
  • 2021-07-16
  • 2013-12-06
  • 2022-08-16
相关资源
最近更新 更多