选择 Pandas DataFrame 的第二个 MultiIndex 级别作为索引器
Posted
技术标签:
【中文标题】选择 Pandas DataFrame 的第二个 MultiIndex 级别作为索引器【英文标题】:Selecting the 2nd MultiIndex Level of Pandas DataFrame as an Indexer 【发布时间】: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_index
和set_index
?
或者有没有更好的方法来实现两次不同时间之间的行过滤?
我正在使用 Python 3.7.4 和 pandas 0.25.1。如果允许更好的解决方案,愿意升级到新版本
【问题讨论】:
【参考方案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_values
和pd.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
之外?是把代码语句分成两行吗?以上是关于选择 Pandas DataFrame 的第二个 MultiIndex 级别作为索引器的主要内容,如果未能解决你的问题,请参考以下文章
Python Pandas - 当我从第二个 Dataframe 添加两列时,Dataframe 列被吞下 [重复]
Pandas:如何在第二个 DataFrame 的另一列中查找子字符串位置