Python在所有可能的变量组合中创建新的列/属性

时间:2016-05-12 18:29:59

标签: python numpy pandas dataframe

如果我有一个带有变量A,B,C,D,E的数据框,我怎样才能创建一个for或while循环来创建变量,方法是使用所有变量和所有可能的数学运算符对现有变量进行所有可能的组合( +, - ,/,*)

从具有以下变量的数据框开始:

A B C D E

这样的人:

A B C D E A + B A + C A + D A + E A * B ...

4 个答案:

答案 0 :(得分:2)

解决方案

您想使用numpy

import numpy as np

vars = [1, 2, 3]

np.concatenate([
        np.add.outer(vars, vars),
        np.subtract.outer(vars, vars),
        np.multiply.outer(vars, vars),
        np.divide.outer(vars, vars)]).flatten()

看起来像:

array([ 2,  3,  4,  3,  4,  5,  4,  5,  6,  0, -1, -2,  1,  0, -1,  2,  1,
        0,  1,  2,  3,  2,  4,  6,  3,  6,  9,  1,  0,  0,  2,  1,  0,  3,
        1,  1])

解释

# All possible additions
print np.add.outer(vars, vars)

# All possible subtractions
print np.subtract.outer(vars, vars)

# All possible multiplications
print np.multiply.outer(vars, vars)

# All possible divisions
print np.divide.outer(vars, vars)

看起来像这样:

[[2 3 4]
 [3 4 5]
 [4 5 6]]

[[ 0 -1 -2]
 [ 1  0 -1]
 [ 2  1  0]]

[[1 2 3]
 [2 4 6]
 [3 6 9]]

[[1 0 0]
 [2 1 0]
 [3 1 1]]

答案 1 :(得分:2)

您可以使用producteval来评估每种可能的组合。这些是使用字典理解保存的,然后与原始数据连接起来。

from itertools import product

df = pd.DataFrame({'A': [1, 2], 'B': [3, 4], 'C': [5, 6]})

transformations = {"".join(p): eval("df.loc[:, '{0}'] {1} df.loc[:, '{2}']".format(*p))
                   for p in product(df, list('+-/*'), df)}
transformations = pd.concat([df, pd.DataFrame(transformations)], axis=1)

>>> transformations
   A  B  C  A+A  A+B  A+C  A-A  A-B  A-C  A/A ...   C+C  C-A  C-B  C-C  C/A  C/B  C/C  C*A  C*B  C*C
0  1  3  5    2    4    6    0   -2   -4    1 ...    10    4    2    0    5    2    1    5   15   25
1  2  4  6    4    6    8    0   -2   -4    1 ...    12    4    2    0    3    2    1   12   24   36

[2 rows x 39 columns]

答案 2 :(得分:0)

循环不是实现此目的的最有效方法。但是,我认为在这种情况下,使用它们有必要。

所以,假设你已经说过你想要使用迭代(循环)而不是第三方库来进行元素操作。我们可以使用生成器有效地(或尽可能高效地)这样做。我就是这样做的:

for item in calculations:
    op, val, res = item
    preped_res = str.join(
        ' | ', ["{:^6.2g}".format(val) for val in res]
    )

    print(" {}  {}  {:.2g}  = | {} |".format(data, op, val, preped_res))

现在让我们显示结果:

[1, 2, 3, 4, 5]  *  1  = |   1    |   2    |   3    |   4    |   5    |
[1, 2, 3, 4, 5]  *  2  = |   2    |   4    |   6    |   8    |   10   |
[1, 2, 3, 4, 5]  *  3  = |   3    |   6    |   9    |   12   |   15   |
[1, 2, 3, 4, 5]  *  4  = |   4    |   8    |   12   |   16   |   20   |
[1, 2, 3, 4, 5]  *  5  = |   5    |   10   |   15   |   20   |   25   |
[1, 2, 3, 4, 5]  +  1  = |   2    |   3    |   4    |   5    |   6    |
[1, 2, 3, 4, 5]  +  2  = |   3    |   4    |   5    |   6    |   7    |
[1, 2, 3, 4, 5]  +  3  = |   4    |   5    |   6    |   7    |   8    |
[1, 2, 3, 4, 5]  +  4  = |   5    |   6    |   7    |   8    |   9    |
[1, 2, 3, 4, 5]  +  5  = |   6    |   7    |   8    |   9    |   10   |
[1, 2, 3, 4, 5]  -  1  = |   0    |   1    |   2    |   3    |   4    |
[1, 2, 3, 4, 5]  -  2  = |   -1   |   0    |   1    |   2    |   3    |
[1, 2, 3, 4, 5]  -  3  = |   -2   |   -1   |   0    |   1    |   2    |
[1, 2, 3, 4, 5]  -  4  = |   -3   |   -2   |   -1   |   0    |   1    |
[1, 2, 3, 4, 5]  -  5  = |   -4   |   -3   |   -2   |   -1   |   0    |
[1, 2, 3, 4, 5]  /  1  = |   1    |   2    |   3    |   4    |   5    |
[1, 2, 3, 4, 5]  /  2  = |  0.5   |   1    |  1.5   |   2    |  2.5   |
[1, 2, 3, 4, 5]  /  3  = |  0.33  |  0.67  |   1    |  1.3   |  1.7   |
[1, 2, 3, 4, 5]  /  4  = |  0.25  |  0.5   |  0.75  |   1    |  1.2   |
[1, 2, 3, 4, 5]  /  5  = |  0.2   |  0.4   |  0.6   |  0.8   |   1    |

看起来像:

$('#barcodescanr').change(function(){
     $('#ui-id-1 li:first-child').trigger('click');
 });

希望这能回答你的问题。但如果有任何我错过的东西,请随时告诉我,我们会看到我们能做些什么。

答案 3 :(得分:0)

如果我理解您的问题,reindexitertools是您的朋友

In [21]: import pandas as pd

In [22]: import numpy as np

In [23]: df = pd.DataFrame({'a':np.arange(5), 'b':np.arange(5), 'c':np.arange(5)
    ...: })

In [24]: df
Out[24]: 
   a  b  c
0  0  0  0
1  1  1  1
2  2  2  2
3  3  3  3
4  4  4  4

In [26]: operations = ['*', '/', '-', '+']

In [30]: new_columns = list(''.join([a,b,c]) for a,b,c in itertools.product(s1,s2,s1) if a!=c ) # joins the permutations of the three elements, and returns those where the first is not repeated i.e. a*a, b-b, etc. You can remove the last if to get all of them

In [31]: new_columns
Out[31]: 
['a*b',
 'a*c',
 'a/b',
 'a/c',
 'a-b',
 'a-c',
 'b*a',
 'b*c',
 'b/a',
 'b/c',
 'b-a',
 'b-c',
 'c*a',
 'c*b',
 'c/a',
 'c/b',
 'c-a',
 'c-b']

In [33]: df.reindex(columns=[*df.columns, *new_columns], fill_value=np.nan) # rewrites the df using by unpacking the existing columns, and also the new columns. Fill the new empty places with `NaN`.
Out[33]: 
   a  b  c  a*b  a*c  a/b  a/c  a-b  a-c  b*a ...   b/a  b/c  b-a  b-c  c*a  \
0  0  0  0  NaN  NaN  NaN  NaN  NaN  NaN  NaN ...   NaN  NaN  NaN  NaN  NaN   
1  1  1  1  NaN  NaN  NaN  NaN  NaN  NaN  NaN ...   NaN  NaN  NaN  NaN  NaN   
2  2  2  2  NaN  NaN  NaN  NaN  NaN  NaN  NaN ...   NaN  NaN  NaN  NaN  NaN   
3  3  3  3  NaN  NaN  NaN  NaN  NaN  NaN  NaN ...   NaN  NaN  NaN  NaN  NaN   
4  4  4  4  NaN  NaN  NaN  NaN  NaN  NaN  NaN ...   NaN  NaN  NaN  NaN  NaN   

   c*b  c/a  c/b  c-a  c-b  
0  NaN  NaN  NaN  NaN  NaN  
1  NaN  NaN  NaN  NaN  NaN  
2  NaN  NaN  NaN  NaN  NaN  
3  NaN  NaN  NaN  NaN  NaN  
4  NaN  NaN  NaN  NaN  NaN

您可以根据需要更改函数''.join()并获得相同的结果。