按多指标级别的子集选择
Selecting by subset of multiindex level
玩具示例
假设我有下面显示的数据框 df
C
L0 L1 L2
0 w P 11
Q 9
R 21
S 4
x P 3
Q 0
R 23
S 20
y P 19
Q 0
R 7
S 13
z P 17
Q 0
R 5
S 1
1 w P 8
Q 2
R 12
S 0
x P 22
Q 14
R 2
S 18
y P 6
Q 0
R 16
S 15
z P 10
Q 0
R 8
S 0
注意df
的行是用3级多索引索引的
我可以为L2
级别的每个值找到C
列的最小值,如下:
In [58]: df.groupby(level='L2').min()
Out[58]:
C
L2
P 3
Q 0
R 2
S 0
类似地,以下表达式显示了 L2
的值,其中此最小值大于 0:
In [59]: df.groupby(level='L2').min() > 0
Out[59]:
C
L2
P True
Q False
R True
S False
问题:我如何select原始数据帧df
的行对应于L2
的值,其中最小值的 C
大于 0?
在这个简单的示例中,问题归结为 select 计算 df
的行,其 L2
值为 'P'
或 'R'
。因此,通过将 L2='P'
的行与 L2='R'
.
的行连接起来,不难解决问题。
然而,在我想到的应用程序中,这样的解决方案变得笨拙,因为这里的 L2
级别有 ~2000 个值,其中大约一半的最小值大于 0。
因此,我正在寻找一种更具可扩展性的方法来解决这个 select离子问题。
数据
L0 L1 L2 C
0 w P 11
0 w Q 9
0 w R 21
0 w S 4
0 x P 3
0 x Q 0
0 x R 23
0 x S 20
0 y P 19
0 y Q 0
0 y R 7
0 y S 13
0 z P 17
0 z Q 0
0 z R 5
0 z S 1
1 w P 8
1 w Q 2
1 w R 12
1 w S 0
1 x P 22
1 x Q 14
1 x R 2
1 x S 18
1 y P 6
1 y Q 0
1 y R 16
1 y S 15
1 z P 10
1 z Q 0
1 z R 8
1 z S 0
这是一种方法
存储所需的 L2
个值
In [413]: m = df.groupby(level='L2').min() > 0
In [414]: m
Out[414]:
C
L2
P True
Q False
R True
S False
使用,get_level_values(index_level_name).isin(to_be_filtered)
只过滤需要的值。
In [415]: df[df.index.get_level_values('L2').isin(m.loc[m.C, :].index)]
Out[415]:
C
L0 L1 L2
0 w P 11
R 21
x P 3
R 23
y P 19
R 7
z P 17
R 5
1 w P 8
R 12
x P 22
R 2
y P 6
R 16
z P 10
R 8
这是另一种方式。使用、变换和子集选择
In [430]: df[(df.groupby(level='L2').transform('min') > 0).C]
Out[430]:
C
L0 L1 L2
0 w P 11
R 21
x P 3
R 23
y P 19
R 7
z P 17
R 5
1 w P 8
R 12
x P 22
R 2
y P 6
R 16
z P 10
R 8
详情
In [416]: m.loc[m.C, :].index
Out[416]: Index([u'P', u'R'], dtype='object', name=u'L2')
玩具示例
假设我有下面显示的数据框 df
C
L0 L1 L2
0 w P 11
Q 9
R 21
S 4
x P 3
Q 0
R 23
S 20
y P 19
Q 0
R 7
S 13
z P 17
Q 0
R 5
S 1
1 w P 8
Q 2
R 12
S 0
x P 22
Q 14
R 2
S 18
y P 6
Q 0
R 16
S 15
z P 10
Q 0
R 8
S 0
注意df
的行是用3级多索引索引的
我可以为L2
级别的每个值找到C
列的最小值,如下:
In [58]: df.groupby(level='L2').min()
Out[58]:
C
L2
P 3
Q 0
R 2
S 0
类似地,以下表达式显示了 L2
的值,其中此最小值大于 0:
In [59]: df.groupby(level='L2').min() > 0
Out[59]:
C
L2
P True
Q False
R True
S False
问题:我如何select原始数据帧df
的行对应于L2
的值,其中最小值的 C
大于 0?
在这个简单的示例中,问题归结为 select 计算 df
的行,其 L2
值为 'P'
或 'R'
。因此,通过将 L2='P'
的行与 L2='R'
.
然而,在我想到的应用程序中,这样的解决方案变得笨拙,因为这里的 L2
级别有 ~2000 个值,其中大约一半的最小值大于 0。
因此,我正在寻找一种更具可扩展性的方法来解决这个 select离子问题。
数据
L0 L1 L2 C
0 w P 11
0 w Q 9
0 w R 21
0 w S 4
0 x P 3
0 x Q 0
0 x R 23
0 x S 20
0 y P 19
0 y Q 0
0 y R 7
0 y S 13
0 z P 17
0 z Q 0
0 z R 5
0 z S 1
1 w P 8
1 w Q 2
1 w R 12
1 w S 0
1 x P 22
1 x Q 14
1 x R 2
1 x S 18
1 y P 6
1 y Q 0
1 y R 16
1 y S 15
1 z P 10
1 z Q 0
1 z R 8
1 z S 0
这是一种方法
存储所需的 L2
个值
In [413]: m = df.groupby(level='L2').min() > 0
In [414]: m
Out[414]:
C
L2
P True
Q False
R True
S False
使用,get_level_values(index_level_name).isin(to_be_filtered)
只过滤需要的值。
In [415]: df[df.index.get_level_values('L2').isin(m.loc[m.C, :].index)]
Out[415]:
C
L0 L1 L2
0 w P 11
R 21
x P 3
R 23
y P 19
R 7
z P 17
R 5
1 w P 8
R 12
x P 22
R 2
y P 6
R 16
z P 10
R 8
这是另一种方式。使用、变换和子集选择
In [430]: df[(df.groupby(level='L2').transform('min') > 0).C]
Out[430]:
C
L0 L1 L2
0 w P 11
R 21
x P 3
R 23
y P 19
R 7
z P 17
R 5
1 w P 8
R 12
x P 22
R 2
y P 6
R 16
z P 10
R 8
详情
In [416]: m.loc[m.C, :].index
Out[416]: Index([u'P', u'R'], dtype='object', name=u'L2')