2015-10-06 42 views
0

我有六个numpy数组,我需要转换成一个数组或甚至更好,一个列表(如果有一个更快的方式作为tolist()你想推荐我)。无论如何,我需要这个处理来自.gif的图像数据,所以它必须非常快。我最近的尝试以8帧/秒的处理时间结束。我将数组转换为列表,但我很确定它是否可以用数组方法完成,它会更快。排序多个numpy数组成一个像这样:[1,2,.. n,1,2..n]

这些数组具有相同的长度,它们是一维的,长度从4096开始,并填充布尔值。

principial它应该做如下:

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

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

因此,这里是我最近尝试:

for x in range(size): 
    counter += 1 
    print(b0[x] 
    data_bin.insert(0, 0) 
    data_bin.insert(1, 0) 
    data_bin.insert(2, b0[x]) 
    data_bin.insert(3, b1[x]) 
    data_bin.insert(4, r0[x]) 
    data_bin.insert(5, g0[x]) 
    data_bin.insert(6, r1[x]) 
    data_bin.insert(7, g1[x]) 

然后我写data_bin的内存空间,并清除值。我可以在10ms内写入1帧,所以整个程序应花费大约8ms。

为了抑制混乱,我从图像中获取数据格式的数据,并且必须按照正确的顺序获取它们。之后我必须将其转换为字符串,因为这是我写入内存的最快方式。

谢谢:)根据您所需的输出

+0

所以,基本上你要'zip'和'chain'阵列?有点像'[x for y in zip([1,3,5],[2,4,6])for x in y]',快一点,用numpy? –

+0

我还不确定你的第一个例子与第二个例子相关。你确定预定的订单是正确的吗? 'r0,r1,g0,g1,b0,b1'与'a'和'b'有什么关系? –

+0

@tobias_k对不起,第一个例子只是它应该做的一个演示,第二个例子来自我的代码,我没有改变什么。所以orde应该像'code [0,0,b0 [x],b1 [x],r0 [x],g0 [x],r1 [x],g1 [x]](前两位是抵消)。然后重复,直到x = 4096 – InvAdErZz

回答

1

看来你是一个接一个地从六个输入中插入个元素,但是从最后一个元素开始直到每个输入的第一个元素。基本上这是一个连接过程,零点定期附加(2+6)。

一种方法能够有效地做到这一点,而不是循环,将与np.concatenate -

size = len(b0) # Must be 4096 

# Initialize output as a 2D array with zeros that would also hold all elements 
# from the six inputs 
out = np.zeros((size,8),dtype=b0.dtype) 

# Leave first two elements in each row and 
# put inputs-concatenated and flipped version into the output array 
out[:,2:] = np.concatenate((b0,b1,r0,g0,r1,g1)).reshape(-1,size)[:,::-1].T 

# Finally convert to list if needed 
data_bin_out = out.ravel().tolist() 

运行测试和验证输出 -

1)设置输入:

In [2]: # Inputs 
    ...: size = 4096 
    ...: b0 = np.random.randint(2,9,(size)) 
    ...: b1 = np.random.randint(2,9,(size)) 
    ...: r0 = np.random.randint(2,9,(size)) 
    ...: g0 = np.random.randint(2,9,(size)) 
    ...: r1 = np.random.randint(2,9,(size)) 
    ...: g1 = np.random.randint(2,9,(size)) 
    ...: 

2 )定义方法 -

def concat_app(b0,b1,r0,g0,r1,g1): 
    out = np.zeros((size,8),dtype=b0.dtype) 
    out[:,2:] = np.concatenate((b0,b1,r0,g0,r1,g1)).reshape(-1,size)[:,::-1].T 
    return out.ravel().tolist() 

def org_app(b0,b1,r0,g0,r1,g1): 
    data_bin = [] 
    counter = 0 
    for x in range(size): 
     counter += 1 
     data_bin.insert(0, 0) 
     data_bin.insert(1, 0) 
     data_bin.insert(2, b0[x]) 
     data_bin.insert(3, b1[x]) 
     data_bin.insert(4, r0[x]) 
     data_bin.insert(5, g0[x]) 
     data_bin.insert(6, r1[x]) 
     data_bin.insert(7, g1[x]) 
    return data_bin 

3)时序和验证:

In [4]: %timeit org_app(b0,b1,r0,g0,r1,g1) 
1 loops, best of 3: 556 ms per loop 

In [5]: %timeit concat_app(b0,b1,r0,g0,r1,g1) 
1000 loops, best of 3: 648 µs per loop 

In [6]: concat_app(b0,b1,r0,g0,r1,g1) == org_app(b0,b1,r0,g0,r1,g1) 
Out[6]: True 
+0

我必须道歉!您的解决方案比@RutkerKassies解决方案快得多。两者都在为我的目的而工作,但不是约50ms(@Rutker),它大约需要566μs,因为您的验证也被破坏了。谢谢 !! :) – InvAdErZz

+0

@InvAdErZz并不感到惊讶。 'np.concatenate'在内部用于其他堆栈funcs,比如'np.hstack','np.vstack'等等,所以你可以避免使用它的func调用。看到这里的一些相关的基准 - http://stackoverflow.com/a/32697426/3293881 – Divakar

2

我会说:

np.dstack((a, b)).flatten() 

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

但背景是有点不清楚。你从什么类型的阵列开始?无论如何,我会尽可能坚持使用Numpy,并避免大量列表操作。按元素插入列表元素可能会导致列表中的许多重新分配,因为大小会继续扩大。这是没有必要的,因为您现在已经事先确定了尺寸。

+0

是的,正是我期待的!谢谢:) – InvAdErZz

相关问题