我有以下格式的pandas DataFrame:
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,新行的索引标签为“红色”。最后,我试图添加三行,将索引值分组:
理想的输出看起来像这样:
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,为每个计算列应用map函数然后重新转置,但我想大熊猫有一种更有效的方法,可能使用.append()
。
编辑:
我优雅的预设列表解决方案(最初使用.transpose()
但我使用.groupby()
和.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答案的灵活性(见下文)。
答案 0 :(得分: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范围内的所有行组合在一起,或者其他任何行)。
答案 1 :(得分: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
根据您示例中的数字,我假设“&gt; 4”实际上意味着“&gt; = 4”。