0

我有一个以下格式的熊猫数据框:

     a   b   c
0    0   1   2
1    3   4   5
2    6   7   8
3    9  10  11
4   12  13  14
5   15  16  17

我想附加一个计算的行,该行基于给定的项目索引值执行一些数学运算,例如添加一个将索引值 < 2 的所有项目的值相加的行,新行的索引标签为“红色”。最终,我试图添加三行将索引值分组为类别:

  • 索引值 < 2 的项目值总和的行,标记为“红色”
  • 索引值为 1 < x < 4 的项目值总和的行,标记为“蓝色”
  • 索引值 > 3 的项目值总和的行,标记为“绿色”

理想的输出如下所示:

       a   b   c
0      0   1   2
1      3   4   5
2      6   7   8
3      9  10  11
4     12  13  14
5     15  16  17
Red    3   5   7
Blue  15  17  19
Green 27  29  31

我目前的解决方案涉及转置 DataFrame,为每个计算列应用一个映射函数,然后重新转置,但我想 pandas 有一种更有效的方法,可能使用.append().

编辑:我优雅的预设列表解决方案(最初使用.transpose()但我使用.groupby()and改进了它.append()):

df = pd.DataFrame(np.arange(18).reshape((6,3)),columns=['a', 'b', 'c'])
df['x'] = ['Red', 'Red', 'Blue', 'Blue', 'Green', 'Green']
df2 = df.groupby('x').sum()
df = df.append(df2)
del df['x']

我更喜欢 BrenBarn 答案的灵活性(见下文)。

4

2 回答 2

3

这是一种方法:

def group(ix):
    if ix < 2:
        return "Red"
    elif 2 <= ix < 4:
        return "Blue"
    else:
        return "Green"

>>> print d
    a   b   c
0   0   1   2
1   3   4   5
2   6   7   8
3   9  10  11
4  12  13  14
5  15  16  17
>>> print d.append(d.groupby(d.index.to_series().map(group)).sum())
        a   b   c
0       0   1   2
1       3   4   5
2       6   7   8
3       9  10  11
4      12  13  14
5      15  16  17
Blue   15  17  19
Green  27  29  31
Red     3   5   7

对于一般情况,您需要定义一个函数(或 dict)来处理到不同组的映射。然后你就可以使用groupby它通常的能力了。

对于您的特定情况,可以更简单地通过直接切片索引值来完成,如 Dan Allan 所示,但如果您有一个更复杂的情况,即您想要的组不能简单地根据连续块定义行。上面的方法也很容易扩展到您想要创建的组不是基于索引而是基于其他列的情况(即,将列 X 中值在 0-10 范围内的所有行分组在一起,或其他)。

于 2013-05-28T18:36:32.057 回答
2

您说您在未显示的解决方案中使用的“转置”的角色可能由orient关键字参数更自然地发挥,当您从字典构造 DataFrame 时可用。

In [23]: df
Out[23]: 
    a   b   c
0   0   1   2
1   3   4   5
2   6   7   8
3   9  10  11
4  12  13  14
5  15  16  17

In [24]: dict = {'Red': df.loc[:1].sum(), 
                 'Blue': df.loc[2:3].sum(), 
                 'Green': df.loc[4:].sum()}

In [25]: DataFrame.from_dict(dict, orient='index')
Out[25]: 
        a   b   c
Blue   15  17  19
Green  27  29  31
Red     3   5   7

In [26]: df.append(_)
Out[26]: 
        a   b   c
0       0   1   2
1       3   4   5
2       6   7   8
3       9  10  11
4      12  13  14
5      15  16  17
Blue   15  17  19
Green  27  29  31
Red     3   5   7

根据您示例中的数字,我假设“> 4”实际上是指“> = 4”。

于 2013-05-28T18:32:51.193 回答