在 numpy 中子列表中的反序

reverse order within sublist in numpy

提问人:ElaineT 提问时间:8/19/2023 最后编辑:jaredElaineT 更新时间:8/19/2023 访问量:55

问:

我有两个numpy数组:

Values = numpy.array([5, 6, 7, 8, 1, 2, 3, 14, 15, 16])
Lengths = numpy.array([4, 3, 3])   

在 numpy 中颠倒子列表中的顺序以获得此结果的有效方法是什么?

[8, 7, 6, 5, 3, 2, 1, 16, 15, 14]

我已经尝试过循环,但我相信应该有一种更有效的方法使用 numpy 函数来做到这一点。for

python list numpy 反向 子列表

评论

0赞 hpaulj 8/19/2023
对于列表和数组,使用反向索引::-1

答:

1赞 jared 8/19/2023 #1

为此,您可以将数组(使用 np.split)拆分到所需的索引处,由 给出,然后在每个索引反转后连接(使用 np.concatenate)。np.cumsum(Lengths)

import numpy as np

Values = np.array([5, 6, 7, 8, 1, 2, 3, 14, 15, 16])
Lengths = np.array([4, 3, 3])

res = np.concatenate([split[::-1] for split in np.split(Values, np.cumsum(Lengths))])
print(res)

输出:

[ 8  7  6  5  3  2  1 16 15 14]
0赞 vegan_meat 8/19/2023 #2
import numpy as np

Values = np.array([5, 6, 7, 8, 1, 2, 3, 14, 15, 16])
Lengths = np.array([4, 3, 3])

splits = np.split(Values, np.cumsum(Lengths)[:-1]) #splits into 3 parts
reversed_list = [np.flip(split) for split in splits] #flip/reverse all the 3 parts

result = np.concatenate(reversed_list) # join all 3 parts
print(result)
0赞 Obaidullah Zaland 8/19/2023 #3

根据这个讨论,切片是最快的技术之一,你可以用它来分割。以下代码仅使用切片,因此不使用任何额外的空格或复制。

import numpy
Values = numpy.array([5, 6, 7, 8, 1, 2, 3, 14, 15, 16])
Lengths = numpy.array([4, 3, 3])  
start = 0
end = 0
for i in range(len(Lengths)):
  end = end + Lengths[i]
  if i == 0:  ## Isolate the first scenario as splitting doesn't accept -1 as second argument. [end:-1:step] is not valid
    Values[0:end] = Values[end-1::-1]
  else:
    Values[start:end] = Values[end-1:start-1:-1]
  start = end
  print(Values)
  
1赞 mozway 8/19/2023 #4

对于矢量解决方案,您可以使用 np.repeat 制作一个排序器数组,然后使用 np.argsort 对数组进行重新排序

a = np.repeat(np.arange(len(Lengths)), Lengths)[::-1]
# array([2, 2, 2, 1, 1, 1, 0, 0, 0, 0])

out = Values[len(Values)-1-np.argsort(a)]

输出:

array([ 8,  7,  6,  5,  3,  2,  1, 16, 15, 14])

中间:

len(Values)-1-np.argsort(a)
# array([3, 2, 1, 0, 6, 5, 4, 9, 8, 7])
0赞 Alain T. 8/19/2023 #5

您可以构建一个索引列表,以反转相对于每个块的最后一个索引的位置。然后将其用作 values 数组的间接。

import numpy as np

values  = np.array([5, 6, 7, 8, 1, 2, 3, 14, 15, 16])
lengths = np.array([4, 3, 3])

s      = np.cumsum(lengths) - 1
s[1:] += s[:-1] + 1
i      = np.repeat(s, lengths) - np.arange(values.size)


print(values[i])    
# [ 8  7  6  5  3  2  1 16 15 14]