【问题标题】:How to merge 3 Pandas Dataframes based on Timestamp?如何根据时间戳合并 3 个 Pandas 数据框?
【发布时间】:2019-09-15 15:05:51
【问题描述】:

我在 Pandas 中有三个数据框,比如df1, df2 and df3。所有数据帧的第一列是时间戳(日期时间格式,如2017-01-01 12:30:00 等)这是每个第一列的示例:-

df1 TimeStamp
    2016-01-01 12:00:00 
    2016-01-01 12:10:00 
      .....
df2 TimeStamp
    2016-01-01 12:00:00 
    2016-01-01 12:10:00 
      .....
df3 TimeStamp
    2016-13-01 12:00:00 
    2016-13-01 12:30:00 
      .....

如您所见,前两个间隔为 10 分钟,而第三个间隔为 30 分钟。我想做的是将所有 3 个数据帧合并在一起,这样对于由于不可用数据而导致不完全匹配的情况(例如 12:10:00 不适用于第三个数据帧),它将被视为 12:00:00 (前面的测量)用于合并目的。 (但当然,日期应该相同)请注意,所有数据框的大小都不同,但我想根据时间戳将它们合并在一起以进行分析。谢谢!

DESIRED RESULT:
df_final TimeStamp      ..  Columns of df1 Columns of df2 Columns of df3
    2016-13-01 12:00:00
    2016-13-01 12:10:00 
    2016-13-01 12:20:00 

      .....

更多详情基于建议的答案 首先,由于我的数据框(全部 3 个)没有索引作为时间戳,但有列作为时间戳,我将每个索引设置为时间戳:

df1.index = df1.TimeStamp
df2.index = df2.TimeStamp
df3.index = df3.TimeStamp

关于使用这个

u_index = df3.index.union(df2.index.union(df1.index))

我奇怪地得到了一个奇怪的输出,它不是像需要的那样定期间隔 10 分钟。

Index(['2016-01-01 00:00:00.000', '2016-01-01 00:00:00.000',
       '2016-01-01 00:00:00.000', '2016-01-01 00:00:00.000',
    ...
       '2017-12-31 23:50:00.000', '2017-12-31 23:50:00.000',
       '2017-12-31 23:50:00.000', '2017-12-31 23:50:00.000',

      dtype='object', name='TimeStamp', length=3199372)

因此,最终的 df1_n 数据帧的间隔为 30 min 而不是 10 mins(因为索引的联合没有正确完成)。我认为这里出了点问题,一旦建议的第 2 步 (u_index) 正常工作,一切将很容易合并数据框。

【问题讨论】:

  • 对于你给出的例子,你想要的结果是什么?
  • @wwii 所需的结果(添加了一个编辑)将是一个每隔 10 分钟的数据帧,其中日期在所有 3 个中匹配,并且对于时间,因为 df3 的间隔为 30 分钟,我会考虑介于两者之间的测量值(比如 12:10、12:20 倍为 12:00,因为记录不可用)。谢谢

标签: python pandas dataframe datetime timestamp


【解决方案1】:

所以我不能 100% 确定您要求的是如何在将三个数据帧与下一个有效观察值合并后完成缺失值。 如果是这样,这是我发现的最快的方法(不是最优雅的......):

  1. 创建一个新索引,它是三个索引的联合(在您的情况下会产生间隔为 10 分钟的时间戳)。
  2. 根据新索引重新索引所有三个 dfs,同时分别填充缺失值。
  3. 合并三个 dfs 的列(这很容易,因为在第 2 步之后它们将具有相同的索引)。

取一部分数据:

    df1
Out[48]: 
                     val_1
TimeStamp                 
2016-01-01 12:00:00     11
2016-01-01 12:10:00     12
df2
Out[49]: 
                     val_2
TimeStamp                 
2016-01-01 12:00:00     21
2016-01-01 12:10:00     22
df3
Out[50]: 
                     val_3
TimeStamp                 
2016-01-01 12:00:00     31
2016-13-01 12:30:00     32

步骤 NO.1

u_index = df3.index.union(df2.index.union(df1.index))
u_index
Out[38]: Index(['2016-01-01 12:00:00', '2016-01-01 12:10:00', '2016-13-01 12:30:00'], dtype='object', name='TimeStamp')

第二步

df3_n = df3.reindex(index=u_index,method='bfill')
df2_n = df2.reindex(index=u_index,method='bfill')
df1_n = df1.reindex(index=u_index,method='bfill')

第 3 步

df1_n.merge(df2_n,on='TimeStamp').merge(df3_n,on='TimeStamp')
Out[47]: 
                     val_1  val_2  val_3
TimeStamp                               
2016-01-01 12:00:00   11.0   21.0     31
2016-01-01 12:10:00   12.0   22.0     32
2016-13-01 12:30:00    NaN    NaN     32

您可能需要调整最后一行,因为它没有下一行来填充值。但仅此而已。

【讨论】:

  • 感谢您的详细解答。但是,我仍然得到最终的数据帧(您提到的 df1_n 间隔为 30 分钟,而我希望它间隔 10 分钟)。我正在根据您的代码向我的问题添加更多详细信息。如果你能说出出了什么问题,那就太好了。谢谢。
  • 原因我能想到为什么它在您的情况下不起作用:(1.) 索引未排序 - 您可以在使用 index.union 时添加标志 sort=True。 (2.) 元素被重复多次 - 您可以尝试 np.unique(u_index.values) 然后将其转换回熊猫索引。我首先要检查的是 u_index 中整体元素的数量,这应该会告诉您这两个建议中的哪一个会有所帮助。现在让我看看它是否有效:)
  • 再次感谢!在使用第一个建议时,我可以看到 u_index 的长度 = 3428255 这正是我所需要的,但奇怪的是,这些元素被广泛重复。虽然 df1 有 10 分钟间隔的元素,并且它的长度是 3428255,这正是需要的,但结果 u_index 似乎确实有多个重复 & 像这样 Index(['2016-01-01 00:00:00.000', '2016-01-01 00:00:00.000', '2016-01-01 00:00:00.000',...'2017-12-31 23:50:00.000', '2017-12-31 23: 50:00.000'], dtype='object', name='TimeStamp', length=3428255),不像 df1 中的时间戳。
  • 在使用第二个建议时,u_index 以 10 分钟为间隔,array(['2016-01-01 00:00:00.000', '2016-01-01 00:10:00.000', ' 2016-01-01 00:20:00.000, ..., '2017-12-31 23:30:00.000', '2017-12-31 23:40:00.000', '2017-12-31 23: 50:00.000'], dtype=object) 但长度仅为 105264,远低于 3428255。这是原始 df 形状(我希望输出为 df1 形状,并且 df1 以 10 分钟为间隔) df1.shape: ( 3428255, 28) df2.shape: (11362, 94) df3.shape: (34576, 35)谢谢 :-)
  • 你能告诉我为什么 u_index 有 3428255 个整体元素,但不是每隔 10 分钟。在最初的 df1 中,这些间隔是 10 分钟,这让我困惑了好几天。再次感谢您
猜你喜欢
  • 1970-01-01
  • 2021-09-10
  • 2022-07-20
  • 2018-04-28
  • 2021-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-27
相关资源
最近更新 更多