【问题标题】:Numpy - Sorting two ndarrays by single axis of first arrayNumpy - 按第一个数组的单轴对两个 ndarrays 进行排序
【发布时间】:2015-03-25 13:30:11
【问题描述】:

我正在尝试在 numpy 中对两个大型四维数组进行排序。

我想根据第一个数组的轴 2 的值进行排序,并按相同的索引对第二个数组进行排序。两个数组的所有其他轴应保持相同的顺序。

下面的代码做我想要的,但依赖于 python 中的循环,所以它很慢。数组非常大,因此出于性能原因,我真的很想使用已编译的 numpy 操作来使其工作。或者其他一些方法来编译这段代码(Cython?)。

import numpy as np

data = np.random.rand(10,6,4,1)
data2 = np.random.rand(10,6,4,3)

print data[0,0,:,:]
print data2[0,0,:,:]

for n in range(data.shape[0]):
  for m in range(data.shape[1]):

    sort_ids = np.argsort(data[n,m,:,0])

    data[n,m,:,:] = data[n,m,sort_ids,:]
    data2[n,m,:,:] = data2[n,m,sort_ids,:]


print data[0,0,:,:]
print data2[0,0,:,:]

【问题讨论】:

标签: python performance sorting numpy


【解决方案1】:

也许有更好的解决方案,但这应该可行:

sort_ids = np.argsort(data,axis=2)

s1 = data.shape
s2 = data2.shape
d1 = data[np.arange(s1[0])[:,None,None,None],np.arange(s1[1])[None,:,None,None],sort_ids,np.arange(s1[3])[None,None,None,:]]
d2 = data2[np.arange(s2[0])[:,None,None,None],np.arange(s2[1])[None,:,None,None],sort_ids,np.arange(s2[3])[None,None,None,:]]

至少输出与您的代码相同。

【讨论】:

  • 这看起来和我想出的解决方案做的基本相同,但它没有内存开销。谢谢!!
【解决方案2】:

找到了一种方法来完成这项工作。它需要存储一个索引数组,这可能会给我带来一些内存问题,但它的速度更快。带有时序比较的示例代码:

import numpy as np
import time

loops = 1000

data = np.random.rand(100,6,4,1)
data2 = np.random.rand(100,6,4,3)

start = time.time()
for n in range(loops):


  idxs = np.indices(data.shape)
  idxs2 = np.indices(data2.shape)

  sort_ids = np.argsort(data, 2)

  sorted_data = data[idxs[0], idxs[1], sort_ids, idxs[3]]
  sorted_data2 = data2[idxs2[0], idxs2[1], np.repeat(sort_ids, data2.shape[3], 3), idxs2[3]]

print 'Time Elapsed: %5.2f seconds' % (time.time() - start)



start = time.time()
for n in range(loops):

  sorted_data = np.zeros(data.shape)
  sorted_data2 = np.zeros(data2.shape)

  for n in range(data.shape[0]):
    for m in range(data.shape[1]):

      sort_ids = np.argsort(data[n,m,:,0])

      data[n,m,:,:] = data[n,m,sort_ids,:]
      data2[n,m,:,:] = data2[n,m,sort_ids,:]


print 'Time Elapsed: %5.2f seconds' % (time.time() - start)

【讨论】:

    猜你喜欢
    • 2011-02-11
    • 2011-09-03
    • 1970-01-01
    • 2023-04-10
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    相关资源
    最近更新 更多