multipliers = {'A' : 5, 'B' : 10, 'C' : 15, 'D' : 20}
df = pd.util.testing.makeDataFrame() # a random df with columns A,B,C,D
f = lambda x, col: multipliers[col] * x
Is there Pandas non-loop way to apply f
to each column, like df.apply(f, axis = 0, ?)
? What I can achieve with loop is
df2 = df.copy()
for c in df.columns:
df2[c] = f(df[c], c)
(real f
is more complex than the above example, please treat f
as a black box function of two variables, arg1 is data, arg2 is column name)
CodePudding user response:
Use lambda function and for pass column name use x.name
:
np.random.seed(2022)
multipliers = {'A' : 5, 'B' : 10, 'C' : 15, 'D' : 20}
df = pd.util.testing.makeDataFrame() # a random df with columns A,B,C,D
f = lambda x, col: multipliers[col] * x
df2 = df.copy()
for c in df.columns:
df2[c] = f(df[c], c)
print (df2.head())
A B C D
9CTWXXW3ys 2.308860 6.375789 5.362095 -23.354181
yq1PHBltEO 2.876024 1.950080 15.772909 -13.776645
lWtMioDq6A -11.206739 17.691500 -12.175996 25.957264
lEHcq1pxLr -6.510434 -6.004475 14.084401 13.999673
xvL04Y66tm -3.827731 -3.104207 -4.111277 1.440596
df2 = df.apply(lambda x: f(x, x.name))
print (df2.head())
A B C D
9CTWXXW3ys 2.308860 6.375789 5.362095 -23.354181
yq1PHBltEO 2.876024 1.950080 15.772909 -13.776645
lWtMioDq6A -11.206739 17.691500 -12.175996 25.957264
lEHcq1pxLr -6.510434 -6.004475 14.084401 13.999673
xvL04Y66tm -3.827731 -3.104207 -4.111277 1.440596
CodePudding user response:
You can convert your dictionary to series and transform your function to vectorized operation. For example:
df * pd.Series(multipliers)
You can also use the method transform
that accepts a dict of functions:
def func(var):
# return your function
return lambda x: x * var
df.transform({k: func(v) for k, v in multipliers.items()})