我有一个数据框:
df = pd.DataFrame({
"A": [1, 5, 2, 5, 6],
"B": [-12, 23, 5, 22, 35],
"C": [-32, 12, -10, 3, 2],
"D": [2, 13, 6, 2, 8]
})
现在,我想计算
axis=1
的百分比变化,但仅参考所有列的 "A"
,例如 "B"
w.r.t "A"
、"C"
w.r.t "A"
的百分比变化等等。
pct_change
函数执行类似的工作,但它计算我不想要的连续行或列的百分比变化。
现在我正在考虑通过可能的 for 循环并添加百分比或拆分数据帧(如
["A", "B"]
、["A", "C"]
等)来实现此目的,然后分别将 pct_change
应用于所有数据帧。
我认为后一种方法更好,但问题是,
是否有更好的方法可以完成同样的工作?
您可以在pandas中使用divide函数,将所有列与列
A
分开
pct = df.divide(df["A"], axis="index") - 1
pct.head()
结果:
A | B | C | D | |
---|---|---|---|---|
0 | 0.0 | -13.000000 | -33.000000 | 1.000000 |
1 | 0.0 | 3.600000 | 1.400000 | 1.600000 |
2 | 0.0 | 1.500000 | -6.000000 | 2.000000 |
3 | 0.0 | 3.400000 | -0.400000 | -0.600000 |
4 | 0.0 | 4.833333 | -0.666667 | 0.333333 |
您可以模仿
pct_change
w.r.t. A
轻松使用 DataFrame.sub
和 DataFrame.div
满足您的情况。
df.loc[:, 'B':].sub(df['A'], axis=0).div(df['A'], axis=0)
B C D
0 -13.000000 -33.000000 1.000000
1 3.600000 1.400000 1.600000
2 1.500000 -6.000000 2.000000
3 3.400000 -0.400000 -0.600000
4 4.833333 -0.666667 0.333333
您可以使用 **kwargs 到
assign()
"A": [1, 5, 2, 5, 6],
"B": [-12, 23, 5, 22, 35],
"C": [-32, 12, -10, 3, 2],
"D": [2, 13, 6, 2, 8]
})
basecol = "A"
df.assign(**{f"{c}_pct":df[basecol]/df[c] for c in df.columns if c!=basecol})
A | B | C | D | B_pct | C_pct | D_pct | |
---|---|---|---|---|---|---|---|
0 | 1 | -12 | -32 | 2 | -0.0833333 | -0.03125 | 0.5 |
1 | 5 | 23 | 12 | 13 | 0.217391 | 0.416667 | 0.384615 |
2 | 2 | 5 | -10 | 6 | 0.4 | -0.2 | 0.333333 |
3 | 5 | 22 | 3 | 2 | 0.227273 | 1.66667 | 2.5 |
4 | 6 | 35 | 2 | 8 | 0.171429 | 3 | 0.75 |
我的看法是,你从数据框开始
df = pd.DataFrame({
"A": [1, 5, 2, 5, 6],
"B": [-12, 23, 5, 22, 35],
"C": [-32, 12, -10, 3, 2],
"D": [2, 13, 6, 2, 8]
})
然后将 apply 与 lambda 函数一起使用
df.iloc[:,1:].apply(lambda x: x.sub(df["A"]).div(df["A"]))
B C D
0 -13.000000 -33.000000 1.000000
1 3.600000 1.400000 1.600000
2 1.500000 -6.000000 2.000000
3 3.400000 -0.400000 -0.600000
4 4.833333 -0.666667
这是以“A”栏为基础进行百分比变更。