【问题标题】:Subset selected days data in Python在 Python 中对选定的日期数据进行子集化
【发布时间】:2017-10-11 14:59:59
【问题描述】:

我有一些时间序列数据:

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

标签: python pandas dataframe time-series


【解决方案1】:

您需要比较 dates 和测试成员使用 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
...

【讨论】:

    【解决方案2】:

    对不起,误解了你的问题

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

    应该执行所需的操作

    原答案

    请在选择时检查pandas documentation

    你可以轻松做到

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

    【讨论】:

    • 超级方便@MaartenFabre
    • 这仅给出所选日期的第一次观察。我需要选定日期的所有 24 个观察结果
    • 确实是@jezrael。我在看到您的回复之前就开始了编辑
    • 好的,没问题,美好的一天!
    • ps。你用了.loc,而我没有
    【解决方案3】:

    你可以使用.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]
    

    【讨论】:

      【解决方案4】:

      编辑:我已经知道这仅在您使用与查询相同的月份和年份的日期范围时才有效。如需更通用(更好的答案),请参阅@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]
      

      我使用这些来源来回答这个问题:
      - Selecting a subset of a Pandas DataFrame indexed by DatetimeIndex with a list of TimeStamps
      - In Python-Pandas, How can I subset a dataframe by specific datetime index values?
      - return pandas DF column with the number of days elapsed between index and today's date
      - Get weekday/day-of-week for Datetime column of DataFrame
      - https://stackoverflow.com/a/36893416/2254228

      【讨论】:

      • @jezrael 您可以看到我使用了.day,而您使用了.date 当我更改答案时,真的没有看到您已发布。只是不希望您认为我会在不提供资源的情况下尝试说您的卓越是我自己的! :) 很抱歉搞混了 jez。
      • @jezrael 我认为它有效,因为年份和月份是相同的,因为它只是更改的日期(并且他的索引都在同一个月/年)。如果selec_dates 在不同的月份或不同的年份有不同的日子,那就错了。那有意义吗?不过,像往常一样,对于任何可能日期的一般情况,您的答案要好得多!
      • 恭喜 1k ;)
      • @jezrael !! :D :D 我终于到了哈哈。谢谢你的祝贺! ;)
      【解决方案5】:

      使用日期字符串 repr,省略一天中的时间段。

      pd.concat([df1['2014-06-10'] , df1['2014-06-15'], df1['2014-06-20']])
      

      【讨论】:

        猜你喜欢
        • 2015-02-11
        • 2019-12-28
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 2021-06-14
        相关资源
        最近更新 更多