【问题标题】:Need to calculate median for dataframe with multiindex需要计算具有多索引的数据帧的中位数
【发布时间】:2019-12-30 16:19:09
【问题描述】:

我有以下数据:

                                            nmins
mac                 status  
3899255688923906615 problems_group_group    198
                     problems_individual    162
3929325397689943966 problems_group_group    198
                     problems_individual    117
4613397785779760382 problems_group_group    198
                     problems_individual    5
4861652328118504220 problems_group_group    198
                     problems_individual    1078
5035225657878165368 problems_group_group    198
                     problems_individual    140
9405388597739161436 problems_group_group    98
                     problems_individual    83
10100515225827442540 problems_group_group   198
                     problems_individual    106
11478610956449410394 problems_group_group   198
                     problems_individual    103

DataFrame 结构如下:

<class 'pandas.core.frame.DataFrame'>
MultiIndex: 16 entries, (3899255688923906615, problems_group_group) to (11478610956449410394, problems_individual)
Data columns (total 1 columns):
nmins    16 non-null int64
dtypes: int64(1)
memory usage: 375.0+ bytes

我需要为每个 mac 计算比率“problems_individual/problems_group_group”并计算整个数据帧的中位数。 'problems_group_group' 字段可能等于 0 - 这种情况我不需要包括在计算中...... 我曾尝试使用类似 df.groupby('mac').transform() 但不需要成功... 请教我怎么做...

【问题讨论】:

    标签: python pandas dataframe multi-index


    【解决方案1】:

    好的,让我们创建一个类似于你的数据框:

    import pandas as pd
    import numpy as np
    
    iterables = [np.random.randint(10_000, 20_000, 100).astype(str), ["group", "individual"]]
    index = pd.MultiIndex.from_product(iterables, names = ["address", "status"])
    df = pd.DataFrame({"nmins" : np.random.randint(0, 200, len(index))}, index = index)
    

    看起来像这样:

                        nmins
    address status
    16541   group         173
            individual     67
    11304   group          70
            individual    133
    15086   group          69
    ...                   ...
    10851   individual    178
    14781   group         173
            individual    186
    12667   group          93
            individual     44
    

    现在我们可以使用pd.IndexSlice 来施展魔法了,

    我们将用这样的切片将不同的组分开:

    idx = pd.IndexSlice
    individual = df.loc[idx[:, "individual"], "nmins"].values
    group =  df.loc[idx[:, "group"], "nmins"].values
    

    最后,我们用numpy where 调用条件:下面的代码说如果nmins 列,在group 索引处,不等于0,那么以安全的方式执行individual/group 和@987654330 @ 否则。

    xx = np.where(df.loc[idx[:,"group"], "nmins"].ne(0), 
                  np.divide(individual,group, where = group!=0),
                                                             0)
    

    然后你可以像你一样找到中位数:

    np.median(xx[xx!0]) 
    

    在这种情况下,它在概念上可能需要做更多的工作,但在更大的数据帧上效率会大大提高,而且正确考虑 MultiIndex 也很有帮助。

    【讨论】:

      【解决方案2】:

      我似乎找到了解决方法:

      xx = df.groupby('mac').apply(lambda o : 0 if (o.nmins[0] == 0) else o.nmins[1]/o.nmins[0])
      
      xx[xx != 0].median()
      

      【讨论】:

      • ..然后再详细解释一下,以便所有人都可以从中学习,而不仅仅是代码转储。
      【解决方案3】:

      IIUC,你可以试试这样的:

      使用@NaturalFrequency 设置:

      import pandas as pd
      import numpy as np
      
      iterables = [np.random.randint(10_000, 20_000, 100).astype(str), ["group", "individual"]]
      index = pd.MultiIndex.from_product(iterables, names = ["address", "status"])
      df = pd.DataFrame({"nmins" : np.random.randint(0, 200, len(index))}, index = index)
      
      df_out = df.median(level=1).T.eval('ratio = individual / group')
      print(df_out)
      

      输出:

      status  group  individual     ratio
      nmins      97          99  1.020619
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-29
        • 2021-05-01
        • 2018-09-22
        • 2020-08-03
        • 2021-12-13
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多