使用级别获取多索引Pandas DataFrame的最小索引

时间:2016-06-16 17:34:46

标签: python pandas dataframe multi-index

我有一个Pandas DataFrame multiindexed,想要在每个级别的行子集中找到某个列的最小值,并获取这些行的全部内容。

import pandas as pd

idx = pd.MultiIndex.from_product([['v1', 'v2'],
                                  ['record' + str(i) for i in range(1, 7)]])

df = pd.DataFrame([[2., 114], [2., 1140],
                   [3., 114], [3., 1140],
                   [5., 114], [5., 1140],
                   [2., 114], [2., 1140],
                   [3., 114], [3., 1140],
                   [5., 114], [5., 1140]],
                  columns=['col1', 'col2'],
                  index=idx)

我的结构:

                 col1  col2
level1 level2
v1     record1    2.0   114
       record2    2.0  1140
       record3    3.0   114
       record4    3.0  1140
       record5    5.0   114
       record6    5.0  1140
v2     record1    2.0   114
       record2    2.0  1140
       record3    3.0   114
       record4    3.0  1140
       record5    5.0   114
       record6    5.0  1140

示例所需的输出我想要col1 == 5

的另一列的最小值
                 col1  col2
level1 level2
v1     record5    5.0   114
v2     record5    5.0   114

我知道我可以使用比较语句获取行的子集。

df.ix[df['col1'] == 5]

而且我也知道我可以从所有级别中获取该子集中列的最小

df['col2'][df['col1'] == 5].min(level='level1')

如果我想指定级别,那么我可以在特定级别获得1行索引

df.ix['v1', pay_up_file.ix['v1']['col2'][(df.ix['v1']['col1'] == 5)].idxmin()]

但我无法弄清楚是否有一种有效的方法从所有级别获取索引

似乎没有可用的方法:

df['col2'][df['col1'] == 5].idxmin(level='level1')

我可以用这个得到我想要的东西:

df.ix[
  (df['col1'] == 5) & 
  (df['col2'].isin(df['col2'][df['col1'] == 5].min(level='level1').values))
]

但是对于Pandas中的其他内容,是否有更好的方式来获取输出?

2 个答案:

答案 0 :(得分:3)

这应该有效:

df.loc[df.loc[df.col1 == 5.].groupby(level=0).col2.idxmin()]

            col1  col2
v1 record5   5.0   114
v2 record5   5.0   114

注意

我按你认为的那样使用idxmin。但背景很重要。我在groupby(level=0).col2.idxmin()之后使用它,按照您的想法行事col2.idxmin(level=...)

答案 1 :(得分:1)

>>> (df[df.col1 == 5]
     .groupby(level=0, as_index=False).col2
     .apply(lambda group: group.nsmallest(1))
0  v1  record5    114
1  v2  record5    114
dtype: int64

或者...

>>> df[df.col1 == 5].groupby(level=0).col2.nsmallest(1)
v1  v1  record5    114
v2  v2  record5    114
dtype: int64

但我不确定为什么第一级显示两次(即' v1'' v1' ...)。