当前位置: 首页 > 面试题库 >

等于itertools.product的数值

海典
2023-03-14
问题内容

我知道itertools.product要遍历关键字几个维度的列表。例如,如果我有这个:

categories = [
    [ 'A', 'B', 'C', 'D'],
    [ 'E', 'F', 'G', 'H'],
    [ 'I', 'J', 'K', 'L']
]

我用itertools.product()它,我有这样的事情:

>>> [ x for x in itertools.product(*categories) ]
('A', 'E', 'I'),
('A', 'E', 'J'),
('A', 'E', 'K'),
('A', 'E', 'L'),
('A', 'F', 'I'),
('A', 'F', 'J'),
# and so on...

是否有一种等效的,简单的方法可以对numpy数组执行相同的操作?


问题答案:

这个问题已经被问过几次了:

使用numpy构建两个数组的所有组合的数组

第一个链接具有一个有效的numpy解决方案,尽管没有提供基准测试,但据称它比itertools快几倍。该代码由名为pv的用户编写。如果您认为有用,请点击链接并支持他的回答:

import numpy as np

def cartesian(arrays, out=None):
    """
    Generate a cartesian product of input arrays.

    Parameters
    ----------
    arrays : list of array-like
        1-D arrays to form the cartesian product of.
    out : ndarray
        Array to place the cartesian product in.

    Returns
    -------
    out : ndarray
        2-D array of shape (M, len(arrays)) containing cartesian products
        formed of input arrays.

    Examples
    --------
    >>> cartesian(([1, 2, 3], [4, 5], [6, 7]))
    array([[1, 4, 6],
           [1, 4, 7],
           [1, 5, 6],
           [1, 5, 7],
           [2, 4, 6],
           [2, 4, 7],
           [2, 5, 6],
           [2, 5, 7],
           [3, 4, 6],
           [3, 4, 7],
           [3, 5, 6],
           [3, 5, 7]])

    """

    arrays = [np.asarray(x) for x in arrays]
    dtype = arrays[0].dtype

    n = np.prod([x.size for x in arrays])
    if out is None:
        out = np.zeros([n, len(arrays)], dtype=dtype)

    m = n / arrays[0].size
    out[:,0] = np.repeat(arrays[0], m)
    if arrays[1:]:
        cartesian(arrays[1:], out=out[0:m,1:])
        for j in xrange(1, arrays[0].size):
            out[j*m:(j+1)*m,1:] = out[0:m,1:]
    return out

不过,在同一篇文章中,Alex
Martelli(他是SO的一位伟大的Python专家)写道,itertools是完成此任务的最快方法。因此,这是一个快速基准,证明了亚历克斯的话。

import numpy as np
import time
import itertools


def cartesian(arrays, out=None):
    ...


def test_numpy(arrays):
    for res in cartesian(arrays):
        pass


def test_itertools(arrays):
    for res in itertools.product(*arrays):
        pass


def main():
    arrays = [np.fromiter(range(100), dtype=int), np.fromiter(range(100, 200), dtype=int)]
    start = time.clock()
    for _ in range(100):
        test_numpy(arrays)
    print(time.clock() - start)
    start = time.clock()
    for _ in range(100):
        test_itertools(arrays)
    print(time.clock() - start)

if __name__ == '__main__':
    main()

输出:

0.421036
0.06742

因此,您绝对应该使用itertools。



 类似资料:
  • 问题内容: 我有一个数组列表,我想获取数组中元素的笛卡尔积。 我将使用一个示例来使其更加具体… itertools.product似乎可以解决问题,但我只保留了一些细节。 如果我做 我懂了 但是我想要得到的是 我尝试了几种不同的方法: 他们都让我 CP0 代替 CP1 。 有任何想法吗? 提前致谢。 问题答案: 这会将所有对作为单独的参数提供给,然后为您提供它们的笛卡尔积。 您的版本无法正常运行的

  • 问题内容: 从Java 1.5中,你几乎可以互换使用在许多情况下。 但是,我发现代码中存在潜在的缺陷,这让我有些惊讶。 如下代码: 值相等时,似乎无法正确设置不匹配,尽管我无法确定在什么情况下。我在Eclipse中设置了一个断点,发现值都为137,并且检查了布尔表达式,并说它是假的,但是当我越过它时,它会将不匹配设置为true。 将条件更改为: 解决了问题。 谁能阐明为什么会这样?到目前为止,我只

  • 问题内容: 以下内容在Python 3.6中从不打印任何内容 相反,它只是坐在那里烧坏了CPU。问题似乎在于,如果迭代器位于无限空间内,则永远不会返回迭代器,因为它首先评估完整的迭代器。鉴于假设应该是发电机,这令人惊讶。 我本来希望这会开始计数(到无穷大),就像这个生成器的行为(直接从docs取得): 但是,尽管我的生成器立即开始计数,但使用的生成器根本不计数。 其他工具可以达到我的期望。例如,以

  • 问题内容: 经过多次尝试优化代码之后,似乎最后的资源就是尝试使用多个内核来运行以下代码。我不确切地知道如何转换/重组我的代码,以便它可以使用多个内核更快地运行。如果能得到指导以实现最终目标,我将不胜感激。最终目标是能够对数组A和B尽可能快地运行此代码,其中每个数组包含大约700,000个元素。这是使用小数组的代码。700k元素数组已被注释掉。 我想做的是模仿一个称为ismember [2]的MAT

  • 问题内容: PostgreSQL有一个有用的功能,称为。它返回那些传递给它记录的最大价值在这里。 SQLite中是否有任何等效项? 需要注意的是,我只需要使用它来处理2个参数。 问题答案: 参考:https : //sqlite.org/lang_corefunc.html#maxoreunc 多参数max()函数返回具有最大值的参数,如果任何参数为NULL,则返回NULL。多参数max()函数从

  • 问题内容: 我试图从我在主java文件中创建的数组中添加,删除和引用项目,但是我在弄清楚正确的语法时遇到了麻烦。在动作脚本中,它们具有push()和pop()来添加和删除数组中的项目,android中是否有等效项? 问题答案: 在Java中,数组的大小是固定的(初始化后),这意味着您无法在数组中添加或删除项目。 上面的代码段表示整数数组的长度为10。如果不将引用重新分配给新数组,则不能添加第11个