【问题标题】:Get index of the minimum of multi-index Pandas DataFrame using level使用 level 获取多索引 Pandas DataFrame 的最小值的索引
【发布时间】:2016-10-18 08:45:19
【问题描述】:

我有一个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行的index特定级别

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

但我不知道是否有一种有效的方法可以从 所有级别

获取 indexes

似乎没有这样的方法可用:

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 中的所有其他内容,是否有更好的方法来获取我的输出?

【问题讨论】:

  • 它在顶部,但我将其加粗并放置了一些较大的换行符以使其更清晰

标签: python pandas dataframe multi-index


【解决方案1】:

这应该可行:

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=...) 应该一样。

【讨论】:

    【解决方案2】:
    >>> (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' ...)。

    【讨论】:

    • .nth(0) 不会只取第一行,而不是最小值吗?在我的示例中,最小值始终是第一个,但在生产中可能并非总是如此
    猜你喜欢
    • 2020-06-04
    • 1970-01-01
    • 2018-06-09
    • 2020-06-22
    • 2019-04-13
    • 2019-03-17
    • 2019-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多