itertools: Получение комбинаций операций (+ - * /) и столбцов - PullRequest
1 голос
/ 11 июля 2020

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

Каким будет самый быстрый способ сделать это для комбинаций 3 и выше?

Ниже приведен минимальный воспроизводимый пример с комбинациями 2.

import numpy as np
import pandas as pd
from itertools import combinations
from itertools import permutations
from sklearn.datasets import load_boston 

# the dataset
X, y = load_boston(return_X_y=True)
X = pd.DataFrame(X)

combos2 = list(combinations(X.columns,2))
perm3 = list(permutations(X.columns,3))  # how would i do this with out typing out all the permutations
for i in combos2:
    X[f'{i[0]}_X_{i[1]}'] = X.iloc[:,i[0]]*X.iloc[:,i[1]]  # Multiply
    X[f'{i[0]}_+_{i[1]}'] = X.iloc[:,i[0]]+X.iloc[:,i[1]]  # Add
    X[f'{i[0]}_-_{i[1]}'] = X.iloc[:,i[0]]-X.iloc[:,i[1]]  # Subtract
    X[f'{i[0]}_/_{i[1]}'] = X.iloc[:,i[0]]/(X.iloc[:,i[1]]+1e-20)   # Divide

Я думал о способе добавить "операторы + * - /" в комбинации, чтобы его можно записать в меньшем количестве строк, чем вводить все комбинации вручную, но я не знаю, с чего начать?

Мне нужны все заказы: т.е. (a * b + c), (a * b - c), (a * b / c) et c

В идеале не оставлять повторяющихся столбцов, т.е. (a + b + c) и (c + b + a)

Например, если бы у меня было 3 столбца ab c. Мне нужен новый столбец (a * b + c).

Ответы [ 2 ]

1 голос
/ 11 июля 2020

Надеюсь, это поможет вам начать работу:

operators = ['-', '+', '*', '/']
operands = ['a', 'b', 'c']

# find out all possible combination of operators first. So if you have 3 operands, that would be all permutations of the operators, taken 2 at a time. Also append the same expression operator combinations to the list

from itertools import permutations
operator_combinations = list(permutations(operators, len(operands)-1))
operator_combinations.extend([op]*(len(operands)-1) for op in operators)

# create a list for each possible expression, appending it with an operand and then an operator and so on, finishing off with an operand.

exp = []
for symbols in operator_combinations:
    temp = []
    for o,s in zip(operands, symbols):
        temp.extend([o,s])
    temp.append(operands[-1])
    exp.append(temp)

for ans in exp:
    print(''.join(ans))

Вывод:

a-b+c
a-b*c
a-b/c
a+b-c
a+b*c
a+b/c
a*b-c
a*b+c
a*b/c
a/b-c
a/b+c
a/b*c
a-b-c
a+b+c
a*b*c
a/b/c
0 голосов
/ 12 июля 2020

Вот наивное решение, которое выводит комбинации 2 и 3 всех столбцов.

  1. Список комбинаций
  2. Используя пакет операторов, создайте функцию
  3. для l oop комбинации
  4. это может иметь повторяющиеся столбцы, следовательно, дубликаты удаляются
from sklearn.datasets import load_boston 
from itertools import combinations
import operator as op 

X, y = load_boston(return_X_y=True)
X =  pd.DataFrame(X)

comb= list(combinations(X.columns,3))

def operations(x,a,b):
   if (x == '+'): 
      d =  op.add(a,b) 
   if (x == '-'): 
      d =  op.sub(a,b) 
   if (x == '*'): 
      d =  op.mul(a,b)     
   if (x == '/'): # divide by 0 error
      d =  op.truediv(a,(b + 1e-20)) 
   return d


for x in ['*','/','+','-']:
  for y in ['*','/','+','-']:
    for i in comb:
      a = X.iloc[:,i[0]].values
      b = X.iloc[:,i[1]].values
      c = X.iloc[:,i[2]].values
      d = operations(x,a,b)
      e = operations(y,d,c)
      X[f'{i[0]}{x}{i[1]}{y}{i[2]}'] = e
      X[f'{i[0]}{x}{i[1]}'] = d

X = X.loc[:,~X.columns.duplicated()]

...