需要计算具有多索引的数据框的中位数

时间:2019-12-30 16:19:09

标签: python pandas dataframe multi-index

我有以下数据:

                                            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()的东西,但不必成功... 请解释一下该怎么做...

3 个答案:

答案 0 :(得分:0)

我似乎已经找到了解决方法:

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

xx[xx != 0].median()

答案 1 :(得分:0)

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

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列不等于零,则执行{{1} }并以安全的方式individual/group

0

然后,您可以像以前一样找到的中位数:

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

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

答案 2 :(得分:0)

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