【问题标题】:How to pass a numpy array of lists to a function (fancy indexing)如何将一个 numpy 列表数组传递给函数(花式索引)
【发布时间】:2020-05-25 22:52:43
【问题描述】:

我想用 numpy 以矢量化的方式使用这个函数:

def example(testing, index):
    return np.sum(testing[index], axis = 1)

假设我们创建了我们的测试数组和索引数组:

test = np.arange(0, 20)
indices = np.array([[0, 2], [1, 3], [0, 3], [1, 2], [3, 4]])

它完成了我的预期,为数组中的每个列表将列表中带有索引的元素相加:

Input: example(test, indices)
Output: [2 4 3 3 7]

但是,如果我尝试使用可变长度的索引列表,

indices = np.array([[0, 2, 3], [1, 3], [0, 3], [1, 2], [3, 4]])
Input: example(test, indices)
Output: IndexError: arrays used as indices must be of integer (or boolean) type

如果不遍历 indices 数组,我无法让 numpy 执行此功能。我知道 numpy 在第一种情况下创建了一个二维数组,但不是在第二种情况下,但我不确定为什么它无法对一维数组执行矢量化元素操作。由于这些数组在现实生活中实际上非常大并且用于并行化函数,因此我想像第一个示例一样以 numpy 风格的矢量化方式执行此操作。

【问题讨论】:

  • 那不是列表数组,而是多维数组
  • 您是否考虑过使用带有 1 或 0 条目的掩码?然后,您可以使用矩阵乘法来计算总和 (dot)。
  • 我正在考虑这个选项,但我不确定如何在不使用 for 循环或类似迭代的情况下从不均匀列表中创建掩码。

标签: python arrays pandas numpy vectorization


【解决方案1】:

indices 的第一个版本确实是一个二维整数数组 - indices.shape 返回 (5, 2)print(indices) 给出:

array([[0, 2],
       [1, 3],
       [0, 3],
       [1, 2],
       [3, 4]])

然而,第二个是列表对象的一维数组:

array([list([0, 2, 3]), list([1, 3]), list([0, 3]), list([1, 2]),
       list([3, 4])], dtype=object)

这里根本不需要向量化,因为这些列表不是 numpy 向量。我相信你可以做的最好的矢量化操作是将indices创建为数组列表而不是列表数组:

indices = [np.array(x) for x in [[0, 2, 3], [1, 3], [0, 3], [1, 2], [3, 4]]]

然后重新定义函数来处理这个问题:

def example(testing, index):
    return [ np.sum(testing[i]) for i in index ]

print(example(test, indices)) 
# prints [5, 4, 3, 3, 7]

【讨论】:

  • 感谢您的快速回复。我知道元素是列表对象,但是向量化应该沿着 numpy 轴发生。因此,该函数应该一次对所有列表对象执行。
  • 关键是要避免列表推导和其他缓慢的迭代。
  • 没有“一次”。它仍然是一个循环,只是它是用 C 实现的,因此比 Python 循环快得多。但这种速度是以降低灵活性为代价的——在这种特殊情况下,索引数组需要是整数数组,而不是列表数组。
  • numpy 中的 "vectorization" 表示使用已编译的方法。在大多数情况下,它们使用多维数组,例如您的第一个示例。第二个是带有列表元素的 1d。快速编译的方法不适用于此。没有axis=1
  • 感谢您的耐心等待,这是迄今为止最快的解决方案(尽管我的计算机用了 14.2 微秒,而简单的列表理解用了 15.5 微秒,所以差别不大)。我同意,我应该写而不是“立即”写的是“使用预编译代码”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多