I have a dataframe as:
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]
})
Now, I want to calculate the percentage change on axis=1
but with reference to just "A"
for all the columns like the percentage change for "B"
wrt "A"
, "C"
wrt "A"
and so on.
The pct_change
function does a similar job but it calculates the percent change for successive rows or columns which I don't want.
Right now I'm thinking of acheiving this by probably a for loop and adding on the percentages OR splitting the dataframe like ["A", "B"]
, ["A", "C"]
, so forth and then applying pct_change
to all separately.
The latter approach is I think better, but the question is,
Is there an even better approach which will do the same job?
You can use divide function in pandas, diving all columns with column A
pct = df.divide(df["A"], axis="index") - 1
pct.head()
Results:
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 |
You can emulate pct_change
wrt A
easily with DataFrame.sub
and DataFrame.div
for your case.
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
You can use ** kwargs to 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 |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.