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

numpy中的ND版本的itertools.combinations

岳凯康
2023-03-14
问题内容

我想为numpy实现itertools.combinations。基于此讨论,我有一个适用于一维输入的函数:

def combs(a, r):
    """
    Return successive r-length combinations of elements in the array a.
    Should produce the same output as array(list(combinations(a, r))), but 
    faster.
    """
    a = asarray(a)
    dt = dtype([('', a.dtype)]*r)
    b = fromiter(combinations(a, r), dt)
    return b.view(a.dtype).reshape(-1, r)

输出是有意义的:

In [1]: list(combinations([1,2,3], 2))
Out[1]: [(1, 2), (1, 3), (2, 3)]

In [2]: array(list(combinations([1,2,3], 2)))
Out[2]: 
array([[1, 2],
       [1, 3],
       [2, 3]])

In [3]: combs([1,2,3], 2)
Out[3]: 
array([[1, 2],
       [1, 3],
       [2, 3]])

但是,最好将它扩展到ND输入,其中附加的维度仅使您可以快速地一次进行多个调用。因此,从概念上讲,如果combs([1, 2, 3], 2)产生了[1, 2], [1, 3], [2, 3],然后 combs([4, 5, 6], 2)产生了[4, 5], [4, 6], [5, 6],那么combs((1,2,3) and (4,5,6), 2)应该产生[1, 2], [1, 3], [2, 3] and [4, 5], [4, 6], [5, 6]“和”仅代表平行的行或列(无论哪个有意义)。(同样,对于其他尺寸)

我不确定:

  1. 如何使尺寸以与其他函数工作方式一致的逻辑方式工作(例如某些numpy函数如何具有axis=参数以及默认的轴0。因此,轴0应该是我正在组合的轴,而所有轴其他轴仅代表并行计算?)
  2. 如何使上述代码与ND配合使用(现在我得到ValueError: setting an array element with a sequence.
  3. 有更好的方法dt = dtype([('', a.dtype)]*r)吗?

问题答案:

您可以使用itertools.combinations()创建索引数组,然后使用NumPy的精美索引:

import numpy as np
from itertools import combinations, chain
from scipy.special import comb

def comb_index(n, k):
    count = comb(n, k, exact=True)
    index = np.fromiter(chain.from_iterable(combinations(range(n), k)), 
                        int, count=count*k)
    return index.reshape(-1, k)

data = np.array([[1,2,3,4,5],[10,11,12,13,14]])

idx = comb_index(5, 3)
print(data[:, idx])

输出:

[[[ 1  2  3]
  [ 1  2  4]
  [ 1  2  5]
  [ 1  3  4]
  [ 1  3  5]
  [ 1  4  5]
  [ 2  3  4]
  [ 2  3  5]
  [ 2  4  5]
  [ 3  4  5]]

 [[10 11 12]
  [10 11 13]
  [10 11 14]
  [10 12 13]
  [10 12 14]
  [10 13 14]
  [11 12 13]
  [11 12 14]
  [11 13 14]
  [12 13 14]]]


 类似资料:
  • 问题内容: 我想要一个2d NumPy数组(x,y)的列表,其中每个x分别位于{-5,-4.5,-4,-3.5,…,3.5、4、4.5、5}中,并且与y相同。 我可以做 然后遍历所有可能的对,但是我敢肯定有更好的方法… 我想要一些看起来像这样的东西: 但是顺序并不重要。 问题答案: 您可以使用它,它通常比在一步中创建数组要方便得多: 对于类似linspace的功能,请用一个复数代替步(即),该复数

  • 问题内容: 如何查看我使用的NumPy版本? (仅供参考,此问题已被编辑,因为问题和答案都不是特定于平台的。) 问题答案:

  • 我用pip安装了numpy,版本1.15 然而,当我使用python导入numpy时,我得到了版本1.7.1 这个numpy是从哪里来的,我怎样才能禁用它? 我检查了sys.path的所有文件夹,并删除了Numpy版本1.7.1的文件夹 导入系统路径['''/usr/lib/python2.7','/usr/lib/python2.7/plat-x86_64-linux-gnu','/usr/li

  • 问题内容: 有谁知道HTA文件使用的JavaScript版本。 当前正在创建一些脚本文件-并尝试利用 当作为HTA运行时-指出对象不支持该属性或方法的错误。我已经将其作为HTM文件运行以进行检查-完全没有问题。 因此,我只能假设它使用的是旧版JavaScript引擎。有人可以确认吗? 问题答案: 使用的JavaScript(或JScript)版本取决于三件事:已安装的Interner Explor

  • 以下的宏为configure脚本管理版本号。使用它们是可选的。 宏: AC_PREREQ version) 确保使用的是足够新的Autoconf版本。如果用于创建configure的Autoconf的版本比version 要早,就在标准错误输出打印一条错 误消息并不会创建configure。例如:AC—PREREQ(1.8) 如果你的'configure.in'依赖于在不同Autoconf版本中改

  • 当我将mvn项目导入Intellij时,它生成的jar文件不包括版本。但是mvn生成的jar具有格式。所以我最终得到了两个jar文件,一个有版本,另一个没有版本。当然,我可以在Intellij设置中更改模块名称以包括版本。但当我更改pom文件时,它将被重置。 也许其他人有更好的主意?