Python all possible products between columns

I have a matrix X with a zero value, and I would like to add to this matrix as new variables all possible products between two columns.

So if X=(x1,x2,x3) I want X=(x1,x2,x3,x1x2,x2x3,x1x3)

Is there an elegant way to do this? I think the combination of numpy and itertools should work

EDIT: Very good answers, but they think X is a matrix? So x1, x1, .. x3 can end up being arrays?

EDIT: A Real Example

a=array([[1,2,3],[4,5,6]])
+3
source share
3 answers

Itertools should be here.

a = [1, 2, 3]
p = (x * y for x, y in itertools.combinations(a, 2))
print list(itertools.chain(a, p))

Result:

[1, 2, 3, 2, 3, 6] # 1, 2, 3, 2 x 1, 3 x 1, 3 x 2
+3
source

I think Samy's solution is pretty good. If you need to use numpy, you can change this a bit:

from itertools import combinations
from numpy import prod

x = [1, 2, 3]
print x + map(prod, combinations(x, 2))

Gives the same result as Samy's solution:

[1, 2, 3, 2, 3, 6]
+3
source

, Samy pure-Python, itertools.combinations :

from itertools import combinations, chain

def all_products1(a):
    p = (x * y for x, y in combinations(a, 2))
    return list(chain(a, p))

, , , numpy.triu_indices, :

import numpy as np

def all_products2(a):
    x, y = np.triu_indices(len(a), 1)
    return np.r_[a, a[x] * a[y]]

:

>>> data = np.random.uniform(0, 100, (10000,))
>>> timeit(lambda:all_products1(data), number=1)
53.745754408999346
>>> timeit(lambda:all_products2(data), number=1)
12.26144006299728

A solution using numpy.triu_indicesalso works for multidimensional data:

>>> np.random.uniform(0, 100, (3,2))
array([[ 63.75071196,  15.19461254],
       [ 94.33972762,  50.76916376],
       [ 88.24056878,  90.36136808]])
>>> all_products2(_)
array([[   63.75071196,    15.19461254],
       [   94.33972762,    50.76916376],
       [   88.24056878,    90.36136808],
       [ 6014.22480172,   771.41777239],
       [ 5625.39908354,  1373.00597677],
       [ 8324.59122432,  4587.57109368]])

If you want to work with columns, not rows, use:

def all_products3(a):
    x, y = np.triu_indices(a.shape[1], 1)
    return np.c_[a, a[:,x] * a[:,y]]

For instance:

>>> np.random.uniform(0, 100, (2,3))
array([[ 33.0062385 ,  28.17575024,  20.42504351],
       [ 40.84235995,  61.12417428,  58.74835028]])
>>> all_products3(_)
array([[   33.0062385 ,    28.17575024,    20.42504351,   929.97553238,
          674.15385734,   575.4909246 ],
       [   40.84235995,    61.12417428,    58.74835028,  2496.45552756,
         2399.42126888,  3590.94440122]])
+2
source

All Articles