У меня есть dataframe, который выглядит так
d = {'A': [10, 20, 30, 40], 'B': [20, 30, 40, 50],'C': [30, 40, 50, 60]}
df = pd.DataFrame(data=d)
A B C
10 20 30
20 30 40
30 40 50
40 50 60
Я пытаюсь построить цикл таким образом, чтобы он создавал три новых столбца (по одному на каждой итерации), используя сложную формулу, в которой только один из них увеличивается на 10%, в то время как остальные два остаются одинаковыми на каждой итерации.
Формула, применяемая каждый раз: sqrt (((A ** 2) * B) + ((B ** 2) * C))
Таким образом, желаемый результат -
A B C X_A X_B X_C
10 20 30 120.08 129.30 123.29
20 30 40 224.77 238.24 227.16
30 40 50 351.51 369.32 352.14
40 50 60 496.79 519.13 494.98
Каким будет самый простой способ достичь этого?
eval
Мы можем использовать некоторую динамическую интерполяцию строк и pandas.DataFrame.eval
ТРЕБУЕТСЯ Python 3.6
fbase = '(((({0:}) ** 2) * ({1:})) + ((({1:}) ** 2) * ({2:}))) ** .5'.format
df.eval(f"""\
X_A = {fbase('1.1 * A', 'B', 'C')}
X_B = {fbase('A', '1.1 * B', 'C')}
X_C = {fbase('A', 'B', '1.1 * C')}
""")
A B C X_A X_B X_C
0 10 20 30 120.083304 129.305839 123.288280
1 20 30 40 224.766546 238.243573 227.156334
2 30 40 50 351.511024 369.323706 352.136337
3 40 50 60 496.789694 519.133894 494.974747
Достаточно динамического, но не требует Python 3.6
df.eval("""\
X_A = ((((1.1 * A) ** 2) * (B)) + (((B) ** 2) * (C))) ** .5
X_B = '((((A) ** 2) * (1.1 * B)) + (((1.1 * B) ** 2) * (C))) ** .5'
X_C = ((((A) ** 2) * (B)) + (((B) ** 2) * (1.1 * C))) ** .5
""")
A B C X_A X_B X_C
0 10 20 30 120.083304 129.305839 123.288280
1 20 30 40 224.766546 238.243573 227.156334
2 30 40 50 351.511024 369.323706 352.136337
3 40 50 60 496.789694 519.133894 494.974747
def f(m):
A, B, C = m.T
return (((A ** 2) * B) + ((B ** 2) * C)) ** .5
v = df.values
m = np.eye(3) * .1 + np.ones((3, 3))
r = f((v * m[:, None]).reshape(-1, 3)).reshape(3, -1)
df.assign(**dict(zip('X_A X_B X_C'.split(), r)))
A B C X_A X_B X_C
0 10 20 30 120.083304 129.305839 123.288280
1 20 30 40 224.766546 238.243573 227.156334
2 30 40 50 351.511024 369.323706 352.136337
3 40 50 60 496.789694 519.133894 494.974747
У вас есть два вопроса.
Возможно, вы не знали об этом. Тип данных данных - строка. Нам нужно сначала преобразовать в int
df=df.astype(int)
Затем мы используем div
и add
pd.concat([df,df.div(10).add(df.sum(1),0).add_prefix('X_')],axis=1)
Out[1082]:
A B C X_A X_B X_C
0 10 20 30 61 62 63
1 20 30 40 92 93 94
2 30 40 50 123 124 125
3 40 50 60 154 155 156
(df.A^2*df.B+df.B^2*df.C).pow(1/2)