我正在尝试在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]
但这当然非常低效,我需要将其分组回格式。
这样做的正确方法是什么?
答案 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')
但转换更好