Генерация матрицы столбцов для всех столбцов в пандах - PullRequest
2 голосов
/ 28 сентября 2019

У меня есть датафрейм, состоящий из 6 столбцов.Какой самый быстрый способ создать матрицу, которая выполняет следующие действия:

Шаг 1) col1 * col1a, col2 * col2a, col3 * col3a, col4 * col4a

Шаг 2) col_new =(col1 * col1a) -col2 * col2a) / (col1a-col2a)

Использование цикла for - один из вариантов, но что может быть быстрее, если это сделать.

import pandas as pd
df=pd.DataFrame()
df['col1']=[100,200,300,400,500]
df['col1a']=[6,71,8,90,10]
df['col2']=[600,700,800,1900,100]
df['col2a']=[6,17,8,9,10]
df['col3']=[100,220,300,440,500]
df['col3a']=[1,22,3,44,5]

df[1x2]=(df['col1']*df['col1a']-df['col2']*df['col2a'])/(df['col1a']-df['col2a'])

Мне нужно иметь комбинации столбцов 1x3,1x4,1x5,2x3,2x4 и так далее ...

Ответы [ 2 ]

1 голос
/ 28 сентября 2019

Итак, по-видимому, мой первый ответ соответствовал только исходному вопросу: Вот ответ на обновленный вопрос:

from itertools import combinations
from functools import partial

primary_columns = df.columns[~df.columns.str.endswith("a")]

combs = combinations(primary_columns, 2)

def column_comparison(first, second, df):
    return  (df[first]*df[first+"a"]-df[second]*df[second+"a"])/(df[first+"a"] - df[second+"a"])

dct = {'{first}X{second}'.format(first=comb[0].lstrip("col"), second=comb[1].lstrip("col")): 
       partial(column_comparison, comb[0], comb[1]) for comb in combs}

Итак, мы создали словарь, который содержит название нужных столбцов и правильную функцию,

Теперь мы можем использовать assign

df.assign(**dct)

, чтобы получить

   col1  col1a  col2  col2a  col3  col3a         1X2         1X3          2X3
0   100      6   600      6   100      1        -inf  100.000000   700.000000
1   200     71   700     17   220     22   42.592593  191.020408 -1412.000000
2   300      8   800      8   300      3        -inf  300.000000  1100.000000
3   400     90  1900      9   440     44  233.333333  361.739130    64.571429
4   500     10   100     10   500      5         inf  500.000000  -300.000000 

В предыдущей версии я использовалЛямбда здесь, но это не работало - проверьте здесь для объяснения.Я понял это только после нахождения решения с использованием частичного.

1 голос
/ 28 сентября 2019

Вот как я подойду к этому:

def new_col(df, col1, col2):
    """
    Add a new column, modifying the dataframe inplace.

    col1: int
        column counter in the first column name
    col2: int
        column counter in the second column name
    """
    nr = (
        df.loc[:, f"col{col1}"] * df.loc[:, f"col{col1}a"]
        - df.loc[:, f"col{col2}"] * df.loc[:, f"col{col2}a"]
    )
    dr = df.loc[:, f"col{col1}a"] - df.loc[:, f"col{col2}a"]

    df.loc[:, f"col{col1}X{col2}"] = nr / dr

Я назову эту функцию с желаемыми комбинациями столбцов.Например:

new_col(df, 1, 2)

Выход:

enter image description here

Вызов будет выполнен из цикла.

...