【问题标题】:Selecting the 2nd MultiIndex Level of Pandas DataFrame as an Indexer选择 Pandas DataFrame 的第二个 MultiIndex 级别作为索引器
【发布时间】:2020-06-05 02:56:49
【问题描述】:

我有一个带有多索引的 pandas DataFrame,我想在其中选择上午 11 点到下午 1 点之间的所有行。

import pandas as pd

data = [
    ('Jack', '2020-01-01 10:00:00', 12),
    ('Jack', '2020-01-01 11:00:00', 13),
    ('Jack', '2020-01-01 12:00:00', 14),
    ('Jack', '2020-01-01 13:00:00', 15),
    ('Jack', '2020-01-01 14:00:00', 16),
    ('Ryan', '2020-01-01 10:00:00', 34),
    ('Ryan', '2020-01-01 11:00:00', 35),
    ('Ryan', '2020-01-01 12:00:00', 36),
    ('Ryan', '2020-01-01 13:00:00', 37),
    ('Ryan', '2020-01-01 14:00:00', 38),
]
df = pd.DataFrame(data, columns=['name', 'datetime', 'score']).set_index(['name','datetime'])
#                           score
# name datetime                  
# Jack 2020-01-01 10:00:00     12
#      2020-01-01 11:00:00     13
#      2020-01-01 12:00:00     14
#      2020-01-01 13:00:00     15
#      2020-01-01 14:00:00     16
# Ryan 2020-01-01 10:00:00     34
#      2020-01-01 11:00:00     35
#      2020-01-01 12:00:00     36
#      2020-01-01 13:00:00     37
#      2020-01-01 14:00:00     38

我当前的解决方案需要将所有多索引转换为常规列,将datetime 列转换为索引器,然后用于选择所需的行。然后重建多索引。

df = df.reset_index()
indexer = pd.DatetimeIndex(df['datetime'])
df = df.loc[indexer.indexer_between_time('11:00', '13:00')].set_index(['name', 'datetime'])
#                           score
# name datetime                  
# Jack 2020-01-01 11:00:00     13
#      2020-01-01 12:00:00     14
#      2020-01-01 13:00:00     15
# Ryan 2020-01-01 11:00:00     35
#      2020-01-01 12:00:00     36
#      2020-01-01 13:00:00     37

问题:是否可以直接使用第二层多索引作为索引器,从而避免reset_indexset_index

或者有没有更好的方法来实现两次不同时间之间的行过滤?

我正在使用 Python 3.7.4 和 pandas 0.25.1。如果允许更好的解决方案,愿意升级到新版本

【问题讨论】:

    标签: python pandas datetime multi-index


    【解决方案1】:
    df.loc[(slice(None),slice('2020-01-01 11:00:00','2020-01-01 13:00:00')),:]
    

    输出:

                              score
    name datetime                  
    Jack 2020-01-01 11:00:00     13
         2020-01-01 12:00:00     14
         2020-01-01 13:00:00     15
    Ryan 2020-01-01 11:00:00     35
         2020-01-01 12:00:00     36
         2020-01-01 13:00:00     37
    

    【讨论】:

      【解决方案2】:

      您可以直接将索引与get_level_valuespd.IndexSlice 一起使用:

      indexer = (pd.DatetimeIndex(df.index.get_level_values('datetime'))
                 .indexer_between_time('11:00', '13:00'))
      df.loc[pd.IndexSlice[:, df.index.get_level_values('datetime')[indexer]], :]     
      

                                score
      name datetime                  
      Jack 2020-01-01 11:00:00     13
           2020-01-01 12:00:00     14
           2020-01-01 13:00:00     15
      Ryan 2020-01-01 11:00:00     35
           2020-01-01 12:00:00     36
           2020-01-01 13:00:00     37
      

      【讨论】:

      • 为什么必须将外括号放在pd.DatetimeIndex 之外?是把代码语句分成两行吗?
      猜你喜欢
      • 2019-01-26
      • 2021-06-18
      • 2015-07-19
      • 2018-02-03
      • 2021-03-27
      • 2018-07-23
      • 2017-12-21
      相关资源
      最近更新 更多