Перебор столбцов панд и вычисление новых столбцов в каждой итерации - PullRequest
0 голосов
/ 29 августа 2018

У меня есть датафрейм, похожий на этот

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

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

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 голосов
/ 29 августа 2018

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

1-й, может быть, вы не знали об этом. Тип данных данных - строка. Сначала нам нужно конвертировать в 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...