根据pandas中的行值划分列

时间:2016-12-06 16:27:41

标签: python pandas

我正在尝试在Pandas中进行一个看起来很明显的计算,但经过几次尝试后我没有找到如何正确地做到这一点。

我有一个如下所示的数据框:

df = pd.DataFrame([["A", "a", 10.0],
                   ["A", "b", 12.0],
                   ["A", "c", 13.0],
                   ["B", "a", 5.0 ],
                   ["B", "b", 6.0 ],
                   ["B", "c", 7.0 ]])

第一列是测试名称,第二列是类,第三列是时间。每个测试通常都在表中,包含3个类。

这是正确的格式,可以这样绘制:

sns.factorplot(x="2", y="0", hue="1", data=df,
               kind="bar")

因此,对于每个测试,我得到一组3个小节,每个小节一个。

但是我想更改数据框,以便第2列中的每个值都不是绝对值,而是与“a”类比较的比率。

所以我想将其改为:

df = pd.DataFrame([["A", "a", 1.0],
                   ["A", "b", 1.2],
                   ["A", "c", 1.3],
                   ["B", "a", 1.0],
                   ["B", "b", 1.2],
                   ["B", "c", 1.4]])

我能够提取系列,更改索引以便它们匹配,进行计算,例如:

df_a = df[df[1] == "a"].set_index(0)
df_b = df[df[1] == "b"].set_index(0)
df_b["ratio_a"] = df_b[2] / df_a[2]

但这当然非常低效,我需要将其分组回格式。

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

您可以使用groupby/transform('first')查找每个组中的第一个值:

import pandas as pd
df = pd.DataFrame([["A", "a", 10.0],
                   ["A", "b", 12.0],
                   ["A", "c", 13.0],
                   ["B", "b", 6.0 ],
                   ["B", "a", 5.0 ],
                   ["B", "c", 7.0 ]])
df = df.sort_values(by=[0,1])
df[2] /= df.groupby(0)[2].transform('first')

产量

   0  1    2
0  A  a  1.0
1  A  b  1.2
2  A  c  1.3
3  B  a  1.0
4  B  b  1.2
5  B  c  1.4

答案 1 :(得分:2)

您也可以通过一些索引对齐来执行此操作。

df1 = df.set_index(['test', 'class'])
df1 / df1.xs('a', level='class')

但转换更好