根据索引标签对MultiIndex pandas df中的行求和

时间:2017-02-09 14:00:04

标签: python pandas

如果我的pandas.DataFrame看起来像这样:

         Probability
0 1 2 3          
C H C C  0.058619
H H C H  0.073274
C H C H  0.195398
C H H H  0.113982
C H H C  0.009770
C C C C  0.087929
H C H H  0.005234
H H H C  0.003664
H H C C  0.021982
C C H C  0.004187
H C H C  0.000449
C C H H  0.048849
H C C C  0.009421
H H H H  0.042743
C C C H  0.293096
H C C H  0.031403

索引是len(4)的元组,其顺序对应于长度为4的所有序列和2个字母的字母['H','C']。在H位置[i for i in df.index]对行进行求和的最佳方法是什么?

df.ix['H'].sum()功能正常,但我看不出如何概括为“任何情况”方法。例如,无论序列有多长或者多于2个字母的字母,我都需要能够执行相同的计算。此外,df.ix['H']很难,因为它似乎不接受通配符,即df.ix['*','H']用于索引位置为H的所有序列。是否有人有任何建议?感谢

2 个答案:

答案 0 :(得分:1)

设置

要创建与您提供的示例相对应的虚拟数据框,我使用了以下内容:

import pandas as pd
import numpy as np
import random

# define sequence and target
sequence = ["H", "C"]
target = "H"

# define shapes
size_col = 4
size_row = 100

# create dummy data and dummy columns
array_indices = np.random.choice(sequence, size=(size_row, size_col))
array_value = np.random.random(size=(size_row, 1))
array = np.concatenate([array_indices, array_value], axis=1)

col_indices = ["Idx {}".format(x) for x in range(size_col)]
col_values = ["Probability"]
columns = col_indices + col_values

# create pandas data frame
df = pd.DataFrame(array, columns=columns)
df[col_values] = df[col_values].astype(float)

结果pandas.DataFrame如下所示:

>>> print(df.head())

Idx 0   Idx 1   Idx 2   Idx 3   Probability
  C       C       C       H     0.892125
  C       H       C       H     0.633699
  C       C       C       C     0.228546
  H       C       H       C     0.766639
  C       H       C       C     0.379930

您数据框的唯一区别是重置索引(使用df.reset_index()时会得到相同的内容)。

解决方案

现在,要获取所有索引的目标值的行总和,您可以使用以下内容:

bool_indices = df[col_indices] == target
result = bool_indices.apply(lambda x: df.loc[x, col_values].sum())

首先,您创建一个新数据框,其布尔值对应于包含每行目标值的每个索引列。

第二,您使用这些布尔系列作为索引列来定义实际值列的子集,最后对其应用sum()等任意方法。

结果如下:

>>> print(result)

                   Idx 0       Idx 1      Idx 2       Idx 3
Probability     23.246007   23.072544   24.775996   24.683079

此解决方案在输入顺序,目标和数据形状方面非常灵活。

此外,如果要使用通配符进行切片,可以在原始数据框示例中使用pandas.IndexSlice,例如:

idx = pd.IndexSlice

# to get all rows which have the "H" at second index
df.loc[idx[:, "H"], :]

# to get all rows which have the "H" at third index
df.loc[idx[:, :, "H"], :]

答案 1 :(得分:0)

pansen建议的另一种解决方案是使用pandas.groupby

    levels=[0,1,2,3]
    for i in range(levels):
        for j in df.groupby(level=i):
            MI=pandas.MultiIndex.from_product([i,j[0]])
            val= float(j[1].sum())
            df_l.append( pandas.DataFrame([val],index=MI))
    return pandas.concat(df_l)