【问题标题】:python all possible products between columnspython列之间所有可能的产品
【发布时间】:2014-02-26 12:35:03
【问题描述】:

我有一个 numpy 矩阵 X,我想将 2 列之间的所有可能乘积作为新变量添加到该矩阵中。

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

有没有一种优雅的方式来做到这一点? 我认为 numpy 和 itertools 的组合应该可以工作

编辑: 很好的答案,但他们是否认为 X 是一个矩阵?那么 x1,x1,.. x3 最终可以是数组吗?

编辑: 一个真实的例子

a=array([[1,2,3],[4,5,6]])

【问题讨论】:

    标签: python numpy itertools


    【解决方案1】:

    Itertools 应该是这里的答案。

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

    结果:

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

    【讨论】:

      【解决方案2】:

      我认为 Samy 的解决方案非常好。如果你需要使用numpy,你可以把它改成这样:

      from itertools import combinations
      from numpy import prod
      
      x = [1, 2, 3]
      print x + map(prod, combinations(x, 2))
      

      提供与 Samy 解决方案相同的输出:

      [1, 2, 3, 2, 3, 6]
      

      【讨论】:

        【解决方案3】:

        如果您的数组很小,那么使用itertools.combinationsSamy's pure-Python solution 应该没问题:

        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
        

        使用numpy.triu_indices的解决方案也适用于多维数据:

        >>> 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]])
        

        如果要对列而不是行进行操作,请使用:

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

        例如:

        >>> 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]])
        

        【讨论】:

        • 我有一个大数组,所以你的解决方案会很好。问题是您正在添加行。我想添加列。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-18
        • 1970-01-01
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 2012-12-26
        • 1970-01-01
        相关资源
        最近更新 更多