умножение всех комбинаций столбцов

#python #python-3.x #pandas #numpy

#python #python-3.x #pandas #numpy

Вопрос:

Я пытаюсь найти эффективный способ умножения каждой комбинации столбцов внутри фрейма данных pandas. Мне удалось добиться этого с помощью itertools, однако, когда размер фрейма данных увеличивается, он резко замедляется. Мне нужно будет выполнить это на фрейме данных размером около (100,1000)

Пример рабочего кода с меньшим фреймом данных приведен ниже,

 import numpy as np
import pandas as pd
from itertools import combinations_with_replacement

df = pd.DataFrame(np.random.randn(3, 10))
new_df = pd.DataFrame()

for p in combinations_with_replacement(df.columns,2):
        title = p
        new_df[title] = df[p[0]]*df[p[1]]  
  

У кого-нибудь есть какие-либо предложения о том, как этого можно достичь?

Комментарии:

1. Я думаю, это должно быть O(n^2) сложно, поскольку никакие вычисления не могут быть сохранены.

Ответ №1:

Комбинируя представление индекса и array.prod(axis) , это выполняется в ~ 100 раз быстрее:

 def f1():
    #with loop
    new_df = pd.DataFrame()
    for p in combinations_with_replacement(df.columns,2):
            title = p
            new_df[title] = df[p[0]]*df[p[1]]
    return new_df

def f2():
    n = len(df.columns)
    ix = np.indices((n,n))[:, ~np.tri(n, k=-1, dtype=bool)]
    return pd.DataFrame(df.values.T[ix.T].prod(1).T, columns=list(map(tuple, ix.T)))
  

Комментарии:

1. В случаях, когда фрейм данных содержит значения столбцов, которые не являются просто расположением индекса, как мне установить новые заголовки столбцов, чтобы показывать результаты того, что было умножено. Например, если df следующий; df = pd.DataFrame(np.random.randn(3, 10), столбцы=[‘a’, ‘b’, ‘c’, ‘d’,’e’,’f’, ‘g’, ‘h’, ‘j’,’k’]) Я бы хотел видеть (‘a’, ‘b’) в виде столбца, а не (0,1)

2. Используйте columns = list(map(tuple, np.array(['a','b','c','d','e','f','g','h','j','k'])[ix.T])) . Обратите внимание, что list(map(tuple это просто для создания кортежей для заголовков столбцов, np.array(...)[ix.T] это для создания массива буквосочетаний.