[英]How to slice one MultiIndex DataFrame with the MultiIndex of another
[英]How to slice multiindex dataframe with list of labels on one level
MultiIndex 数据帧非常强大,但我个人认为没有足够的(清晰的)文档,特别是针对不同类型的切片......这是我的问题:
如何使用标签列表在一个级别上对多索引 dataframe 进行切片? 如果您有解决方案,请帮助我(无需重置索引并将 dataframe 转换为单级索引!这很明显但效率不高)
例如,我们有以下 dataframe:
import pandas as pd
import numpy as np
df = pd.DataFrame(index=range(10))
df['id'] = pd.Series(range(10,20))
df['name'] = [f'name_{id}' for id in range(10,20)]
df['price'] = np.random.rand(df.index.size)
df['date'] = pd.date_range('20200310', '20200319')
df = df.set_index(['id', 'date'])
df
切片一个 label 工作得很好:
df.xs('2020-03-10', level='date', drop_level=False)
但是我们如何才能在该级别上对标签列表进行切片呢?
df.xs(('2020-03-10', '2020-03-11', '2020-03-12'), level='date', drop_level=False)
这导致了一个异常:
但是 Python 文档说“key”参数也可以是一个元组:
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.xs.html
Index.get_level_values
多个值过滤,请使用Index.get_level_values
和Index.isin
和boolean indexing
:
a = df[df.index.get_level_values('date').isin(('2020-03-10', '2020-03-11', '2020-03-12'))]
print (a)
name price
id date
10 2020-03-10 name_10 0.557772
11 2020-03-11 name_11 0.122315
12 2020-03-12 name_12 0.775976
然而 Python 文档说“key”参数也可以是一个元组:
元组可以使用,但工作方式不同 - 您可以通过两个标签进行选择,例如:
b = df.xs((10, '2020-03-10'), drop_level=False)
print (b)
name name_10
price 0.348808
Name: (10, 2020-03-10 00:00:00), dtype: object
c = df.xs((10, '2020-03-10'), level=('id','date'), drop_level=False)
print (c)
name price
id date
10 2020-03-10 name_10 0.239876
像@yatu提到,与其他解决方案IndexSlice
是:
所有的第一级别和最后:
所有列:
df = df.loc[pd.IndexSlice[:, ['2020-03-10', '2020-03-11', '2020-03-12']], :]
print (df)
name price
id date
10 2020-03-10 name_10 0.557488
11 2020-03-11 name_11 0.592082
12 2020-03-12 name_12 0.547747
访问多索引时使用元组是为了解决不同的级别/层次结构。 元组用于此用途,而不是作为在同一层次结构/级别内传递多个项目的一种形式。 对于同一级别内的多个选择,您需要使用其他一些功能,例如一个Jezrael 。
dates = ['2020-03-10', '2020-03-11', '2020-03-12']
filtered_df = df[df.index.get_level_values('date').isin(dates)]
这与@jezrael 提供的答案略有不同。
您可以像这样使用loc()
与slice(None)
结合:
dates = ['2020-03-10', '2020-03-11', '2020-03-12']
df.loc[(slice(None), dates), :]
id date name price
10 2020-03-10 name_10 0.36806
11 2020-03-11 name_11 0.20436
12 2020-03-12 name_12 0.00443
.loc
中的第一个参数是一个在 MultiIndex 中选择行的元组。 slice(None)
从第一级id
获取所有值。 列表dates
过滤第二级date
中的键。 第二个参数:
选择所有列。
在Pandas 文档 - MultiIndex - 高级索引中,您可以找到:
重要的是要注意,在索引方面,元组和列表在 pandas 中的处理方式不同。 元组被解释为一个多级键,而列表用于指定多个键。 或者换句话说,元组 go 水平(遍历级别),垂直列出 go(扫描级别)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.