我有一个数组 a = np.array([2, 2, 2, 3, 3, 15, 7, 7, 9])
继续这样。我想移动这个数组,但不确定是否可以在此处使用 np.roll()
。
我想生成的数组是 [0, 0, 0, 2, 2, 3, 15, 15, 7]
。
如您所见,数组 a
中的第一个类似数字(在本例中为三个“2”)应替换为“0”。然后应该移动所有内容,以便将“3”替换为“2”,将“15”替换为“3”等。理想情况下,我希望在没有任何 for 循环的情况下执行此操作,因为我需要它快速运行。
我意识到这个操作可能有点困惑,所以请提问。
最佳答案
如果你想坚持使用 NumPy,你可以使用 np.unique
来实现。通过使用 return_counts
选项返回每个唯一元素的计数。
然后,简单地滚动值并用 np.repeat
构造一个新数组:
>>> s, i, c = np.unique(a, return_index=True, return_counts=True)
(array([ 2, 3, 7, 9, 15]), array([0, 3, 6, 8, 5]), array([3, 2, 2, 1, 1]))
三个输出分别是:唯一排序元素、第一次遇到唯一元素的索引、每个唯一元素的计数。 p>
np.unique
对值进行排序,因此我们需要先对值和计数进行排序。然后我们可以用 np.roll
移动值:
>>> idx = np.argsort(i)
>>> v = np.roll(s[idx], 1)
>>> v[0] = 0
array([ 0, 2, 3, 15, 7])
或者使用 np.append
, 这需要一个完整的副本:
>>> v = np.append([0], s[idx][:-1])
array([ 0, 2, 3, 15, 7])
最后重新组装:
>>> np.repeat(v, c[idx])
array([ 0, 0, 0, 2, 2, 3, 15, 15, 7])
另一种 - 更通用 - 当 a
中有重复值时可以使用的解决方案。这需要使用 np.diff
.
您可以通过以下方式获取元素的索引:
>>> i = np.diff(np.append(a, [0])).nonzero()[0] + 1
array([3, 5, 6, 8, 9])
>>> idx = np.append([0], i)
array([0, 3, 5, 6, 8, 9])
然后使用 a[idx]
给出值:
>>> v = np.append([0], a)[idx]
array([ 0, 2, 3, 15, 7, 9])
每个元素的计数:
>>> c = np.append(np.diff(i, prepend=0), [0])
array([3, 2, 1, 2, 1, 0])
最后,重新组装:
>>> np.repeat(v, c)
array([ 0, 0, 0, 2, 2, 3, 15, 15, 7])
关于python - 按不同数量移动 numpy 数组中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68772095/