【问题标题】:sort multible numpy arrays into one like: [1,2,..n, 1,2..n]将多个 numpy 数组排序为一个,例如:[1,2,..n, 1,2..n]
【发布时间】:2016-01-03 12:15:06
【问题描述】:

我有六个 numpy 数组,我需要将它们转换成一个数组,甚至更好,一个列表(如果有比 tolist() 更快的方法,你想推荐我)。无论如何,我需要它来处理来自 .gif 的图像数据,所以它必须非常快。我最近的尝试以 8 帧/秒的处理时间结束。我将数组转换为列表,但我很确定如果可以使用数组方法完成它会更快。

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

它应该遵循的原则:

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 写入内存空间并清除该值。我可以在 10 毫秒内写 1 帧,所以整个例程应该花费我大约 8 毫秒。

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

谢谢:)

【问题讨论】:

  • 那么,基本上你想要zipchain 数组?有点像[x for y in zip([1,3,5],[2,4,6]) for x in y],只是更快并使用 numpy?
  • 我仍然不确定您的第一个示例与第二个示例有何关联。你确定预定的顺序是正确的吗? r0, r1, g0, g1, b0, b1ab 有什么关系?
  • @tobias_k 哦,对不起,第一个例子只是它应该做的演示,第二个来自我的代码,我没有改变任何东西。所以顺序应该像code[0, 0, b0[x], b1[x], r0[x], g0[x], r1[x], g1[x]](前两位是偏移量)。然后重复直到 x = 4096
  • 那么,您是否尝试过类似(在普通 Python 中)[(0, 0) + zipped for zipped in zip(b0, b1, r0, g0, r1, g1)]

标签: list python-2.7 sorting numpy beagleboneblack


【解决方案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

【讨论】:

  • 我必须向我道歉!您的解决方案比@RutkerKassies 解决方案快得多。两者都为我的目的工作,但不是约 50 毫秒(@Rutker),它需要大约 566 微秒,因为您的验证也证实了。谢谢 !! :)
  • @InvAdErZz 一点也不惊讶。 np.concatenate 在内部用于其他堆栈函数,如 np.hstacknp.vstack 等,因此您可以避免函数调用开销。请参阅此处了解一些相关的基准测试 - stackoverflow.com/a/32697426/3293881
【解决方案2】:

根据您想要的输出,我会说:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 2013-10-04
    相关资源
    最近更新 更多