在Python中对所选日期数据进行子集筛选

3
我有一些时间序列数据,如下所示:

import pandas as pd    
index = pd.date_range('06/01/2014',periods=24*30,freq='H')
df1 = pd.DataFrame(range(len(index)),index=index)

现在我想要对以下日期的数据进行子集筛选。
selec_dates = ['2014-06-10','2014-06-15','2014-06-20']

我尝试使用以下语句,但它并没有起作用

sub_data = df1.loc[df1.index.isin(pd.to_datetime(selec_dates))]

我做错了什么?是否有其他方法来对所选日期的数据进行子集处理?


@chuckm 他使用了 pd.to_datetime - Maarten Fabré
5个回答

6

您需要比较日期,并使用numpy.in1d进行测试成员身份:

sub_data = df1.loc[np.in1d(df1.index.date, pd.to_datetime(selec_dates).date)]
print (sub_data)
                      a
2014-06-10 00:00:00  216
2014-06-10 01:00:00  217
2014-06-10 02:00:00  218
2014-06-10 03:00:00  219
2014-06-10 04:00:00  220
2014-06-10 05:00:00  221
2014-06-10 06:00:00  222
2014-06-10 07:00:00  223
2014-06-10 08:00:00  224
2014-06-10 09:00:00  225
2014-06-10 10:00:00  226
...

如果想使用isin,就需要创建一个与索引相同的Series
sub_data = df1.loc[pd.Series(df1.index.date, index=df1.index)
                     .isin(pd.to_datetime(selec_dates).date)]
print (sub_data)
                       a
2014-06-10 00:00:00  216
2014-06-10 01:00:00  217
2014-06-10 02:00:00  218
2014-06-10 03:00:00  219
2014-06-10 04:00:00  220
2014-06-10 05:00:00  221
2014-06-10 06:00:00  222
2014-06-10 07:00:00  223
2014-06-10 08:00:00  224
2014-06-10 09:00:00  225
2014-06-10 10:00:00  226
2014-06-10 11:00:00  227
...

3

很抱歉,我误解了你的问题。

df1[pd.Series(df1.index.date, index=df1.index).isin(pd.to_datetime(selec_dates).date)]

需要执行所需的操作。

原始答案

请查看 pandas 文档 中有关选择的内容。

您可以轻松地执行

sub_data = df1.loc[pd.to_datetime(selec_dates)]

非常方便 @MaartenFabre - Phung Duy Phong
这只提供了所选日期的第一次观察。我需要所选日期的所有24次观察。 - Haroon Lone
确实,@jezrael。在看到你的回复之前,我已经开始编辑了。 - Maarten Fabré
好的,没问题,祝您愉快! - jezrael
你在使用.loc,而我没有。 - Maarten Fabré

2
你可以使用`.query()`方法:

(你可以使用.query()方法)

In [202]: df1.query('@index.normalize() in @selec_dates')
Out[202]:
                       0
2014-06-10 00:00:00  216
2014-06-10 01:00:00  217
2014-06-10 02:00:00  218
2014-06-10 03:00:00  219
2014-06-10 04:00:00  220
2014-06-10 05:00:00  221
2014-06-10 06:00:00  222
2014-06-10 07:00:00  223
2014-06-10 08:00:00  224
2014-06-10 09:00:00  225
...                  ...
2014-06-20 14:00:00  470
2014-06-20 15:00:00  471
2014-06-20 16:00:00  472
2014-06-20 17:00:00  473
2014-06-20 18:00:00  474
2014-06-20 19:00:00  475
2014-06-20 20:00:00  476
2014-06-20 21:00:00  477
2014-06-20 22:00:00  478
2014-06-20 23:00:00  479

[72 rows x 1 columns]

2

编辑:我已被告知,这只适用于您正在处理与查询中相同月份和年份的日期范围。对于更一般(更好的)答案,请参见@jezrael的解决方案。

如果您想要像您尝试的那样使用np.in1d.day,则可以在索引上使用它们:

selec_dates = ['2014-06-10','2014-06-15','2014-06-20']

df1.loc[np.in1d(df1.index.day, (pd.to_datetime(selec_dates).day))]

这将按您要求提供给您:
2014-06-10 00:00:00  216
2014-06-10 01:00:00  217
2014-06-10 02:00:00  218
2014-06-10 03:00:00  219
2014-06-10 04:00:00  220
2014-06-10 05:00:00  221
2014-06-10 06:00:00  222
2014-06-10 07:00:00  223
2014-06-10 08:00:00  224
2014-06-10 09:00:00  225
2014-06-10 10:00:00  226
2014-06-10 11:00:00  227
2014-06-10 12:00:00  228
2014-06-10 13:00:00  229
2014-06-10 14:00:00  230
2014-06-10 15:00:00  231
2014-06-10 16:00:00  232
2014-06-10 17:00:00  233
2014-06-10 18:00:00  234
2014-06-10 19:00:00  235
2014-06-10 20:00:00  236
2014-06-10 21:00:00  237
2014-06-10 22:00:00  238
2014-06-10 23:00:00  239
2014-06-15 00:00:00  336
2014-06-15 01:00:00  337
2014-06-15 02:00:00  338
2014-06-15 03:00:00  339
2014-06-15 04:00:00  340
2014-06-15 05:00:00  341
                 ...
2014-06-15 18:00:00  354
2014-06-15 19:00:00  355
2014-06-15 20:00:00  356
2014-06-15 21:00:00  357
2014-06-15 22:00:00  358
2014-06-15 23:00:00  359
2014-06-20 00:00:00  456
2014-06-20 01:00:00  457
2014-06-20 02:00:00  458
2014-06-20 03:00:00  459
2014-06-20 04:00:00  460
2014-06-20 05:00:00  461
2014-06-20 06:00:00  462
2014-06-20 07:00:00  463
2014-06-20 08:00:00  464
2014-06-20 09:00:00  465
2014-06-20 10:00:00  466
2014-06-20 11:00:00  467
2014-06-20 12:00:00  468
2014-06-20 13:00:00  469
2014-06-20 14:00:00  470
2014-06-20 15:00:00  471
2014-06-20 16:00:00  472
2014-06-20 17:00:00  473
2014-06-20 18:00:00  474
2014-06-20 19:00:00  475
2014-06-20 20:00:00  476
2014-06-20 21:00:00  477
2014-06-20 22:00:00  478
2014-06-20 23:00:00  479

[72 rows x 1 columns]

我使用了以下资源来回答这个问题:
- 使用时间戳列表选择由DatetimeIndex索引的Pandas DataFrame的子集
- 在Python-Pandas中,如何按特定日期时间索引值对数据框进行子集筛选?
- 返回Pandas DF列,其中包含索引与今天日期之间经过的天数
- 获取DataFrame的日期时间列的weekday/day-of-week
- https://stackoverflow.com/a/36893416/2254228

@jezrael,你可以看到我使用了.day而你使用了.date。我真的没有看到你发布了回答,当我改变答案时。我不想让你觉得我试图说你的优秀是我的,而没有提供来源!:) 对于混淆jez感到抱歉。 - Chuck
@jezrael 我认为它有效,因为年份和月份相同,只有日期发生变化(而且索引都在同一个月/年中)。如果在 selec_dates 中有不同的日期跨越不同的月份或不同的年份,那么它就是错误的。这样说通了吗?尽管如此,您的答案对于任何可能的日期的一般情况要好得多! - Chuck
恭喜你1K ;) - jezrael
@jezrael !! :D :D 终于到了哈哈。谢谢你说恭喜!;) - Chuck

1
使用日期的字符串表示形式,省略一天中的时间段。
pd.concat([df1['2014-06-10'] , df1['2014-06-15'], df1['2014-06-20']])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接