【问题标题】:merge some data with pandas将一些数据与熊猫合并
【发布时间】:2018-08-21 15:40:27
【问题描述】:

我有一些这样的数据:

df = pd.DataFrame ({'code': ['A', 'A','A' ,'B', 'B','B', 'C'],
                     'type' : ['a', 'a', 'b', 'c', 'c', 'c', 'd'],
                     'start': ['2017-1-1', '2018-5-5', '2017-5-21', '2017-6-6','2017-7-8','2017-8-9','2018-5-1'],
                    'end': ['2017-5-20', 'now', '2017-5-4', '2017-7-7','2017-8-8','now','now']})

╔═══╦══════╦══════╦═══════════╦═══════════╗
║   ║ code ║ type ║ start     ║ end       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 0 ║ A    ║ a    ║ 2017-1-1  ║ 2017-5-20 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 1 ║ A    ║ a    ║ 2018-5-5  ║ now       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 2 ║ A    ║ b    ║ 2017-5-21 ║ 2017-5-4  ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 3 ║ B    ║ c    ║ 2017-6-6  ║ 2017-7-7  ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 4 ║ B    ║ c    ║ 2017-7-8  ║ 2017-8-8  ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 5 ║ B    ║ c    ║ 2017-8-9  ║ now       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 6 ║ C    ║ d    ║ 2018-5-1  ║ now       ║
╚═══╩══════╩══════╩═══════════╩═══════════╝

我想使用 pandas 将其转换为如下所示:

╔═══╦══════╦══════╦═══════════╦═══════════╗
║   ║ code ║ type ║ start     ║ end       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 0 ║ A    ║ a    ║ 2017-1-1  ║ 2017-5-20 ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 1 ║ A    ║ a    ║ 2018-5-5  ║ now       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 2 ║ A    ║ b    ║ 2017-5-21 ║ 2017-5-4  ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 3 ║ B    ║ c    ║ 2017-6-6  ║ now       ║
╠═══╬══════╬══════╬═══════════╬═══════════╣
║ 4 ║ C    ║ d    ║ 2018-5-1  ║ now       ║
╚═══╩══════╩══════╩═══════════╩═══════════╝

需要在 codetype 字段中合并数据,其中 date 值形成连续的日期范围(如日期 [ 2017-6-6]、[2017-7-7]、[2017-7-8]、[2017-8-8]、[2017-8-9]、现在可以合并进入 [2017-6-6] 到 现在)。

如果 日期 不连续,则不应将它们分组/合并,并且不应更改开始和结束。 我怎样才能做到这一点?

【问题讨论】:

  • 你为什么会选择像这样格式化你的数据 D:通过提供输入数据框你做得很好:)
  • 所以您想将连续的时间序列转换为单行?
  • 您希望如何转换数据?从您的示例中我看不出预期的转换是什么。
  • 为什么第 0 行和第 2 行没有合并?
  • 我掩盖了 0 和 2 中的错误,我改变了它。

标签: python pandas merge


【解决方案1】:

试试这个:

grp_helper = df.groupby(['code','type'])\
               .apply(lambda x: (pd.to_datetime(x['start']) - 
                                 pd.to_datetime(x['end'], errors='coerce').shift(1) 
                                 != pd.Timedelta(days=1)).cumsum()).values

df.groupby(['code','type',grp_helper])[['start','end']]\
  .agg({'start':'min','end':'max'}).reset_index().drop('level_2', axis=1)

输出:

  code type      start        end
0    A    a   2017-1-1  2017-5-20
1    A    a   2018-5-5        now
2    A    b  2017-5-21   2017-5-4
3    B    c   2017-6-6        now
4    C    d   2018-5-1        now

【讨论】:

  • 好的,我们首先创建一个 group_helper 数组,它基本上将数据帧分组到 'code' 和 'type' 然后将 end 列向下移动,所以我们可以减去 start 减去 end 来查看是否正好有 1 天差异,如果不是一天,则使用 cumsum 加一。如果它在当天不增加保持与前一行相同的值。因此,创建一组记录。
猜你喜欢
  • 2020-11-23
  • 1970-01-01
  • 2020-10-26
  • 2018-05-07
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多