Перебор столбцов панд и вычисление новых столбцов в каждой итерации

1

У меня есть 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

Каким будет самый простой способ достичь этого?

Теги:
pandas
for-loop

2 ответа

1
Лучший ответ

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

Numpy-иш

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
  • 0
    Спасибо piRSquared. Это сработало отлично! Я пошел на NumPy формулировку
4

У вас есть два вопроса.

Возможно, вы не знали об этом. Тип данных данных - строка. Нам нужно сначала преобразовать в 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
  • 0
    Спасибо Вен. Такой подход выглядит очень перспективным. Я немного обновил свой первоначальный вопрос, чтобы запросить разрешение для моей фактической формулы. Как можно применить многомерную сложную формулу к этому решению?
  • 0
    @kartriter (df.A^2*df.B+df.B^2*df.C).pow(1/2)
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню