在两个并行的大型numpy数组上迭代迭代

时间:2013-03-11 11:54:21

标签: python numpy vectorization

我有两个类型numpy.core.memmap.memmap的大型数组,名为datanew_data,其中包含> 700万个float32项目。

我需要在我正在进行的同一循环中迭代它们。

for i in range(0,len(data)):
  if new_data[i] == 0: continue
  combo = ( data[i], new_data[i] )
  if not combo in new_values_map: new_values_map[combo] = available_values.pop()
  data[i] = new_values_map[combo]

然而这是非常慢的,所以我认为使用numpy的矢量化功能是可行的方法。

是否可以使用索引进行矢量化 - 以便矢量化数组可以将它的项目与另一个数组中的相应项目进行比较?

我想要压缩两个数组,但我想这会导致不合理的开销准备?

是否有其他方法可以优化此操作?

对于上下文:目标是有效地合并两个数组,使得两个数组之间的相应值的每个唯一组合由结果数组中的不同值表示,除了new_data数组中被忽略的零。数组代表3D位图图像。

编辑:available_values是一组尚未在data中使用的值,并且会在对此循环的调用中持续存在。另一方面,new_values_map在每次使用此循环之前重置为空字典。

EDIT2:数据数组只包含整数,即:它初始化为零,然后每次使用此循环时使用不同的new_data,它将填充更多来自available_values的值,即new_data最初是一系列整数。 {{1}}理论上可以是任何东西。

3 个答案:

答案 0 :(得分:2)

在回答关于矢量化的问题时,答案可能是肯定的,尽管你需要澄清available_values包含的内容及其使用方式,因为这是矢量化的核心。

您的解决方案可能看起来像这样......

indices = new_data != 0

data[indices] = available_values

在这种情况下,如果available_values可以被视为一组值,我们将第一个值分配给data中new_data不为0的第一个值,那应该可以正常工作,如只要available_values是一个numpy数组。

假设new_datadata取值0-255,那么您可以构建一个available_values数组,其中包含new_data中每个可能值对的唯一条目以及如下所示的数据:

available_data = numpy.array(xrange(0, 255*255)).reshape((255, 255))
indices = new_data != 0
data[indices] = available_data[data[indices], new_data[indices]]

显然,available_data可以是您想要的任何映射。 available_data中的任何内容都应该非常快(特别是如果你只构造available_data一次)。

答案 1 :(得分:0)

Python为您提供了处理大量数据的强大工具:generatorsiterators

基本上,他们将允许访问您的数据,因为它们是常规列表,而不是立即将它们提取到内存中,而是逐个访问。

如果一次访问两个大型数组,您可以

for item_a, item_b in izip(data, new_data):
   #... do you stuff here

izip创建一个迭代器,它会立即迭代数组的元素,但它会根据您的需要选择片段,而不是一次性完成。

答案 2 :(得分:0)

似乎替换前两行循环产生:

for i in numpy.where(new_data != 0)[0]:
  combo = ( data[i], new_data[i] )
  if not combo in new_values_map: new_values_map[combo] = available_values.pop()
  data[i] = new_values_map[combo]

有预期的效果。

因此,在new_data中遇到零时,循环中的大部分时间花在跳过整个循环上。真的不明白为什么这么多的空迭代如此昂贵,也许有一天我会...