选择/筛选索引为多索引的数据帧行的最常用方法是什么?
- 基于单个值/标签的切片
- 基于一个或多个级别的多个标签进行切片
- 布尔条件和表达式的过滤
- 哪些方法适用于什么情况
为简单起见,假设:
- 输入数据帧没有重复的索引键
- 下面的输入数据帧只有两个级别。(此处显示的大多数解决方案可推广到N个级别)
输入示例:
mux=pd.MultiIndex.from\u数组([ 列表('aaaabbbbbccddddd'), 列表('tuvwtuvtuvw') ],名称=['1','2']) df=pd.DataFrame({'col':np.arange(len(mux))},mux) 上校 12 t0 u 1 v2 W3 b t 4 u 5 v6 w 7 t8 c u 9 v 10 d w 11 t 12 u 13 v 14 w 15
问题1:选择单个项目
如何选择级别“1”中具有“a”的行
col
12
t0
u 1
v2
W3
此外,我如何才能在输出中降低级别“1”
col
二
t0
u 1
v2
W3
问题1b
如何在级别“2”上对值为“t”的所有行进行切片
col
12
t0
b t 4
t8
d t 12
问题2:在一个级别中选择多个值
如何选择级别“一”中项目“b”和“d”对应的行
col
12
b t 4
u 5
v6
w 7
t8
d w 11
t 12
u 13
v 14
w 15
问题2b
如何获得级别“2”中与“t”和“w”对应的所有值
col
12
t0
W3
b t 4
w 7
t8
d w 11
t 12
w 15
问题3:切片单个横截面(x,y)
如何从df检索横截面,即具有特定索引值的单行?具体来说,如何检索('c','u')的横截面,由
col
12
c u 9
问题4:切片多个横截面[(a,b),(c,d),…]
如何选择与('c','u')和('a','w')相对应的两行
col
12
c u 9
a w 3
问题5:每级切片一个项目
如何检索与级别“1”中的“a”或级别“2”中的“t”对应的所有行
col
12
t0
u 1
v2
W3
b t 4
t8
d t 12
问题6:任意切片
如何切片特定的横截面?对于“a”和“b”,我想选择所有子级别为“u”和“v”的行,对于“d”,我想选择子级别为“w”的行
col
12
a u 1
v2
b u 5
v6
d w 11
w 15
问题7将使用由数字级别组成的唯一设置:
np.random.seed(0) mux2=pd.MultiIndex.from_数组([ 列表('aaaabbbbbccddddd'), np.随机选择(10,大小=16) ],名称=['1','2']) df2=pd.DataFrame({'col':np.arange(len(mux2))},mux2) 上校 12 a 50 0 1 3 2 3 3 b 7 4 9 5 3 6 5 7 2 8 c 4 9 7 10 d 6 11 8 12 8 13 1 14 6 15
问题7:在多指标的各个层次上通过数值不等式进行过滤
如何获取级别“2”中的值大于5的所有行
col
12
b 7 4
9 5
c 7 10
d 6 11
8 12
8 13
6 15
注意:这篇文章将而不是讲述如何创建多索引,如何对它们执行赋值操作,或任何与性能相关的讨论(这些是另一次单独讨论的主题)
多索引/高级索引
注意
该员额的结构将如下:
- OP中提出的问题将逐一解决
- 对于每个问题,将演示一种或多种适用于解决此问题并获得预期结果的方法
注意s(与此类似)将提供给有兴趣了解其他功能、实施细节、,
以及其他与当前主题相关的信息。这些便笺已经过修改
通过对文件的梳理和对各种模糊信息的揭露
功能,并从我自己(承认有限)的经验所有代码示例都已在pandas v0.23.4和python3.7上创建和测试。如果有些事情不清楚,或者事实上不正确,或者如果你没有
找到适用于您的用例的解决方案,请随时
建议编辑,在评论中要求澄清,或打开新的
问题……如适用
下面是我们将经常重温的一些常见习语(以下简称四习语)的介绍
-
DataFrame.loc-按标签选择的通用解决方案(+pd.indexlice,用于涉及切片的更复杂应用程序) -
DataFrame.xs-从序列/数据帧中提取特定横截面 -
DataFrame.query-动态指定切片和/或筛选操作(即作为动态计算的表达式)。与其他情况相比,它更适用于某些情况。有关查询多索引的信息,请参见文档的本节 -
使用
多索引生成的掩码进行布尔索引。获取\u级别\u值(通常与索引.isin结合使用,尤其是在使用多个值进行筛选时)。这在某些情况下也非常有用
从这四种习惯用法的角度来看各种切片和过滤问题将有助于更好地理解什么可以应用于给定的情况。了解并非所有习惯用法都同样有效(如果有的话)是非常重要的在任何情况下。如果一个习语没有被列为下面某个问题的潜在解决方案,这意味着该习语不能有效地应用于该问题
问题1
如何选择级别“一”中有“a”的行
col 12 t0 u 1 v2 W3
您可以使用loc,作为适用于大多数情况的通用解决方案:
df.loc['a']]
在这一点上,如果你
TypeError:需要元组,得到str
这意味着你在使用一个较老版本的大熊猫。考虑升级,否则,使用 df.LOC[ [(a,'切片(无)]:] /
或者,您可以在此处使用xs,因为我们提取的是单个横截面。请注意级别和轴参数(此处可以假设合理的默认值)
df.xs('a',level=0,axis=0,drop\u level=False)
#df.xs('a',drop_level=False)
在这里,需要使用drop_level=False参数来防止xs在结果中删除level“one”(我们切片的级别)
这里的另一个选项是使用query:
df.query(";one=='a'";)
如果索引没有名称,则需要将查询字符串更改为“ilevel”0==“a”
最后,使用获取级别值:
df[df.index.get_level_值('one')='a']
#如果您的标高未命名,或者需要按位置(而不是标签)选择,
#df[df.index.get_level_值(0)='a']
此外,我如何才能在输出中降低“1”级
col 二 t0 u 1 v2 W3
这可以通过以下两种方法轻松实现
请注意单字符串参数而不是列表。
或者
df.xs('a',级别=0,轴=0,下降级别=True)
#df.xs('a')
请注意,我们可以省略drop\u level参数(默认情况下,它假定为True)
注意
您可能会注意到,经过筛选的数据帧可能仍然具有所有级别,即使在打印数据帧时没有显示这些级别。例如v=df.loc['a']] 印刷品(五) 上校 12 t0 u 1 v2 W3 打印(v.index) 多索引(级别=['a'、'b'、'c'、'd']、['t'、'u'、'v'、'w'], 标签=[[0,0,0,0],[0,1,2,3], 名称=[“一”、“二”])您可以使用多索引删除这些级别。删除未使用的级别:
v.index=v.index.remove\u unused\u levels()
打印(v.index) 多索引(级别=['a']、['t'、[u'、[v'、[w']], 标签=[[0,0,0,0],[0,1,2,3], 名称=[“一”、“二”])
问题1b
如何在级别“t”上对所有值为“t”的行进行切片