【问题标题】:Python pandas idxmax for multiple indexes in a dataframePython pandas idxmax 用于数据框中的多个索引
【发布时间】:2015-03-10 22:47:24
【问题描述】:

我有一个看起来像这样的系列:

            delivery
2007-04-26  706           23
2007-04-27  705           10
            706         1089
            708           83
            710           13
            712           51
            802            4
            806            1
            812            3
2007-04-29  706           39
            708            4
            712            1
2007-04-30  705            3
            706         1016
            707            2
...
2014-11-04  1412          53
            1501           1
            1502           1
            1512           1
2014-11-05  1411          47
            1412        1334
            1501          40
            1502         433
            1504         126
            1506         100
            1508           7
            1510           6
            1512          51
            1604           1
            1612           5
Length: 26255, dtype: int64

查询在哪里:df.groupby([df.index.date, 'delivery']).size()

每天,我需要提取数量最多的交货单号。我觉得会是这样的:

df.groupby([df.index.date, 'delivery']).size().idxmax(axis=1)

但是,这只会返回整个数据帧的 idxmax;相反,我需要每天的二级 idmax(不是日期,而是交货编号),而不是整个数据帧(即它返回一个向量)。

关于如何实现这一点的任何想法?

【问题讨论】:

标签: python pandas multi-index


【解决方案1】:

假设你有这个系列:

            delivery
2001-01-02  0           2
            1           3
            6           2
            7           2
            9           3
2001-01-03  3           2
            6           1
            7           1
            8           3
            9           1
dtype: int64

如果您希望在每个日期一次交付且具有最大值,您可以使用idxmax

dates = series.index.get_level_values(0)
series.loc[series.groupby(dates).idxmax()]

产量

            delivery
2001-01-02  1           3
2001-01-03  8           3
dtype: int64

如果您希望每个日期所有交付具有最大值,use transform to generate a boolean mask:

mask = series.groupby(dates).transform(lambda x: x==x.max()).astype('bool')
series.loc[mask]

产量

            delivery
2001-01-02  1           3
            9           3
2001-01-03  8           3
dtype: int64

这是我用来生成series的代码:

import pandas as pd
import numpy as np

np.random.seed(1)
N = 20
rng = pd.date_range('2001-01-02', periods=N//2, freq='4H')
rng = np.random.choice(rng, N, replace=True)
rng.sort()
df = pd.DataFrame(np.random.randint(10, size=(N,)), columns=['delivery'], index=rng)
series = df.groupby([df.index.date, 'delivery']).size()

【讨论】:

    【解决方案2】:

    您的示例代码不起作用,因为 idxmax 在 groupby 操作之后执行(因此在整个数据帧上)

    我不确定如何在多级索引上使用 idxmax,所以这里有一个简单的解决方法。

    设置数据:

    import pandas as pd
    d= {'Date': ['2007-04-26', '2007-04-27', '2007-04-27', '2007-04-27',
                 '2007-04-27', '2007-04-28', '2007-04-28'], 
            'DeliveryNb': [706, 705, 708, 450, 283, 45, 89],
            'DeliveryCount': [23, 10, 1089, 82, 34, 100, 11]}
    
    df = pd.DataFrame.from_dict(d, orient='columns').set_index('Date')
    print df
    

    输出

                DeliveryCount  DeliveryNb
    Date                                 
    2007-04-26             23         706
    2007-04-27             10         705
    2007-04-27           1089         708
    2007-04-27             82         450
    2007-04-27             34         283
    2007-04-28            100          45
    2007-04-28             11          89
    

    创建自定义函数:

    诀窍是使用 reset_index() 方法(这样您就可以轻松获得组的整数索引)

    def func(df):
        idx = df.reset_index()['DeliveryCount'].idxmax()
        return df['DeliveryNb'].iloc[idx]
    

    应用它:

    g = df.groupby(df.index)
    g.apply(func)
    

    结果:

    Date
    2007-04-26    706
    2007-04-27    708
    2007-04-28     45
    dtype: int64
    

    【讨论】:

      【解决方案3】:

      如果您有以下数据框(如果需要,您可以随时重置索引:df = df.reset_index()

        Date  Del_Count  Del_Nb
      0  1/1      14      19   <
      1           11      17
      2  2/2      25      29   <
      3           21      27
      4           22      28
      5  3/3      34      36
      6           37      37
      7           31      39   <
      

      要查找每个日期的最大值并提取您可以使用的相关 Del_Count:

      df = df.ix[df.groupby(['Date'], sort=False)['Del_Nb'].idxmax()][['Date','Del_Count','Del_Nb']]
      

      哪个会产生:

       Date  Del_Count  Del_Nb
      0  1/1         14      19
      2  2/2         25      29
      7  3/3         31      39
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-06
        • 1970-01-01
        • 2020-10-22
        • 2013-05-20
        • 2017-05-22
        • 2020-07-17
        • 1970-01-01
        • 2021-02-24
        相关资源
        最近更新 更多