在循环中从Pandas DataFrame创建具有层次索引的子表

1 投票
2 回答
1205 浏览
提问于 2025-04-18 12:00

我想要遍历一个有层级索引的Pandas数据框,并根据“group1”这一层级打印出一些子集。

这是我的数据框:

df = pd.DataFrame({'group1': ['a','a','a','b','b','b','c','c','d','d','d','d','d'],
                        'group2': ['c','c','d','d','d','e','f','f','e','d','d','d','e'],
                        'value1': [1.1,2,3,4,5,6,7,8,9,1,2,3,4],
                        'value2': [7.1,8,9,10,11,12,43,12,34,5,6,2,3]})

df = df.set_index(['group1', 'group2'])

它的样子是这样的:

               value1  value2
group1 group2                
a      c          1.1     7.1
a      c          2.0     8.0
a      d          3.0     9.0
b      d          4.0    10.0
b      d          5.0    11.0
b      e          6.0    12.0
c      f          7.0    43.0
d      f          8.0    12.0
d      e          9.0    34.0
d      d          1.0     5.0
d      d          2.0     6.0
d      d          3.0     2.0
d      e          4.0     3.0

我可以成功地根据group1打印出一个单独的子集,方法是这样的:

print df.xs('a', level=0)  

        value1  value2
group2                
c          1.1     7.1
c          2.0     8.0
d          3.0     9.0

但是我该如何把这个放进一个循环里,以便为'group1'中的每个元素组打印出一个子集呢?

我之前的尝试失败了:

for group1, group2 in df.index: 
    print df.xs(group1, level=0)

这次尝试为每个索引打印了一个子集,而不是把它们分组在一起(希望这样说能让你明白)。

2 个回答

1

这就是groupby的用途(迭代时会给你组名和组内容):

In [13]: for g, grp in df.groupby(level='group1'):
    print grp
   ....:     
               value1  value2
group1 group2                
a      c          1.1     7.1
       c          2.0     8.0
       d          3.0     9.0
               value1  value2
group1 group2                
b      d            4      10
       d            5      11
       e            6      12
               value1  value2
group1 group2                
c      f            7      43
       f            8      12
               value1  value2
group1 group2                
d      e            9      34
       d            1       5
       d            2       6
       d            3       2
       e            4       3

不过大多数情况下,你其实是想对这些数据做点什么,比如:

df.groupby(level='group1').sum()
2

使用 get_level_values 方法可以从索引中提取出某一层级的索引值。此外,还需要使用 unique 方法,因为返回的结果中会有重复的索引值,这些重复值是针对每个子层级的行。

In [35]:

for gp in df.index.get_level_values(0).unique():
    print (df.xs(gp, level=0))
        value1  value2
group2                
c          1.1     7.1
c          2.0     8.0
d          3.0     9.0

[3 rows x 2 columns]
        value1  value2
group2                
d            4      10
d            5      11
e            6      12

[3 rows x 2 columns]
        value1  value2
group2                
f            7      43
f            8      12

[2 rows x 2 columns]
        value1  value2
group2                
e            9      34
d            1       5
d            2       6
d            3       2
e            4       3

[5 rows x 2 columns]

撰写回答