如何将多索引数据框的子集存储在新的数据框中?

2024-09-25 00:33:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样一个多索引数据帧:

import pandas as pd
import numpy as np


df = pd.DataFrame({'ind1': list('aaaaaaaaabbbbbbbbb'),
                   'ind2': list('cccdddeeecccdddeee'),
                   'ind3': list(range(3))*6,
                   'val1': list(range(100, 118)),
                   'val2': list(range(70, 88))})

df_mult = df.set_index(['ind1', 'ind2', 'ind3'])

                val1  val2
ind1 ind2 ind3            
a    c    0      100    70
          1      101    71
          2      102    72
     d    0      103    73
          1      104    74
          2      105    75
     e    0      106    76
          1      107    77
          2      108    78
b    c    0      109    79
          1      110    80
          2      111    81
     d    0      112    82
          1      113    83
          2      114    84
     e    0      115    85
          1      116    86
          2      117    87

我现在可以使用.loc选择它的一个子集,如下所示

^{pr2}$

这就产生了预期的结果

^{3}$

如果我现在想再次选择df_subs的子集,例如

df_subs.loc['a', 'c', :]

工作和付出

      val1  val2
ind3            
0      100    70
1      101    71
2      102    72

但是

df_subs.loc[:, 'c', :]

失败并给出错误

KeyError: 'the label [c] is not in the [columns]'

为什么会失败?在

编辑

最初,我在这篇文章中有两个问题。我把它分成两部分,第二个问题可以找到here。在


Tags: theimportdfasrangeloc子集list
2条回答

通过使用IndexSlice

idx = pd.IndexSlice
df_subs.loc[idx[:, 'c',:],:]
Out[159]: 
                val1  val2
ind1 ind2 ind3            
a    c    0      100    70
          1      101    71
          2      102    72

或者需要在行或列上指定切片

^{pr2}$

.loc[:, 'c', :]无法工作的原因:

应该在.loc说明符中指定所有轴,即索引和列的索引器。在一些模棱两可的情况下,传递的索引器可能会被错误地解释为索引两个轴,而不是对行进行MuliIndex。

Link1

Link2

显然,使用.loc可能会使索引保持其原始形式,直到它们被重置。使用.copy()来避免原始数据帧的任何视图仍然保持multindex值。在

df_subs = df_mult.loc['a', ['c', 'd'], :].copy()

print(df_subs.index)
# MultiIndex(levels=[['a', 'b'], ['c', 'd', 'e'], [0, 1, 2]],
#            labels=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]],
#            names=['ind1', 'ind2', 'ind3'])

此外,按值过滤仍保留multindex值:

^{pr2}$

所以,可以考虑在初始分配之后手动重置索引

df_subs = df_mult.loc['a', ['c', 'd'], :].reset_index()

df_subs = df_subs.set_index(['ind1', 'ind2', 'ind3'])

print(df_subs.index)
# MultiIndex(levels=[['a'], ['c', 'd'], [0, 1, 2]],
#            labels=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]],
#            names=['ind1', 'ind2', 'ind3'])

最后,对于最后一个.loc赋值(#2),根据需要至少提供第一个索引:

df_subs2 = df_subs.loc['a', 'c', :]
#       val1  val2
# ind3            
# 0      100    70
# 1      101    71
# 2      102    72

相关问题 更多 >