根据范围替换numpy数组中的重复元素
Replace duplicate elements in a numpy array based on a range
我有一个 1d numpy 数组 arr
如下:
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
对于重复的元素,我希望随机 select 任何一个包含相同元素的索引,并将其替换为 0
和 arr.shape[0]
之间缺失的值。
例如在给定的数组中,7 出现在索引 1、4 和 9 中。因此,我希望随机 select 1、4 和 9 之间的索引,并通过随机 select 一些元素来设置它的值,比如8,数组中没有。最后,arr
应该包含 arr.shape[0]
个介于 0 和 arr.shape[0] - 1
之间的唯一元素(包括两者)
如何使用 Numpy 高效地执行此操作(可能不需要使用任何显式循环)?
这是一个基于 np.isin
-
def create_uniques(arr):
# Get unique ones and the respective counts
unq,c = np.unique(arr,return_counts=1)
# Get mask of matches from the arr against the ones that have
# respective counts > 1, i.e. the ones with duplicates
m = np.isin(arr,unq[c>1])
# Get the ones that are absent in original array and shuffle it
newvals = np.setdiff1d(np.arange(len(arr)),arr[~m])
np.random.shuffle(newvals)
# Assign the shuffled values into the duplicate places to get final o/p
arr[m] = newvals
return ar
样本运行 -
In [53]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [54]: create_uniques(arr)
Out[54]: array([9, 7, 0, 1, 6, 4, 8, 2, 3, 5])
In [55]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [56]: create_uniques(arr)
Out[56]: array([9, 4, 0, 5, 6, 2, 7, 1, 3, 8])
In [57]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [58]: create_uniques(arr)
Out[58]: array([9, 4, 0, 1, 7, 2, 6, 8, 3, 5])
扩展 Divakar 的答案(我基本上没有 python 方面的经验,所以这可能是一种非常迂回和不 python 的做法,但是):
import numpy as np
def create_uniques(arr):
np.random.seed()
indices = []
for i, x in enumerate(arr):
indices.append([arr[i], [j for j, y in enumerate(arr) if y == arr[i]]])
indices[i].append(np.random.choice(indices[i][1]))
indices[i][1].remove(indices[i][2])
sidx = arr.argsort()
b = arr[sidx]
new_vals = np.setdiff1d(np.arange(len(arr)),arr)
arr[sidx[1:][b[:-1] == b[1:]]] = new_vals
for i,x in enumerate(arr):
if x == indices[i][0] and i != indices[i][2]:
arr[i] = arr[indices[i][2]]
arr[indices[i][2]] = x
return arr
样本:
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(arr)
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
输出:
[9 7 0 4 7 4 2 2 3 7]
[9 7 0 4 6 5 2 1 3 8]
[9 8 0 4 6 5 1 2 3 7]
[9 8 0 4 6 5 2 1 3 7]
[9 7 0 5 6 4 2 1 3 8]
我有一个 1d numpy 数组 arr
如下:
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
对于重复的元素,我希望随机 select 任何一个包含相同元素的索引,并将其替换为 0
和 arr.shape[0]
之间缺失的值。
例如在给定的数组中,7 出现在索引 1、4 和 9 中。因此,我希望随机 select 1、4 和 9 之间的索引,并通过随机 select 一些元素来设置它的值,比如8,数组中没有。最后,arr
应该包含 arr.shape[0]
个介于 0 和 arr.shape[0] - 1
之间的唯一元素(包括两者)
如何使用 Numpy 高效地执行此操作(可能不需要使用任何显式循环)?
这是一个基于 np.isin
-
def create_uniques(arr):
# Get unique ones and the respective counts
unq,c = np.unique(arr,return_counts=1)
# Get mask of matches from the arr against the ones that have
# respective counts > 1, i.e. the ones with duplicates
m = np.isin(arr,unq[c>1])
# Get the ones that are absent in original array and shuffle it
newvals = np.setdiff1d(np.arange(len(arr)),arr[~m])
np.random.shuffle(newvals)
# Assign the shuffled values into the duplicate places to get final o/p
arr[m] = newvals
return ar
样本运行 -
In [53]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [54]: create_uniques(arr)
Out[54]: array([9, 7, 0, 1, 6, 4, 8, 2, 3, 5])
In [55]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [56]: create_uniques(arr)
Out[56]: array([9, 4, 0, 5, 6, 2, 7, 1, 3, 8])
In [57]: arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
In [58]: create_uniques(arr)
Out[58]: array([9, 4, 0, 1, 7, 2, 6, 8, 3, 5])
扩展 Divakar 的答案(我基本上没有 python 方面的经验,所以这可能是一种非常迂回和不 python 的做法,但是):
import numpy as np
def create_uniques(arr):
np.random.seed()
indices = []
for i, x in enumerate(arr):
indices.append([arr[i], [j for j, y in enumerate(arr) if y == arr[i]]])
indices[i].append(np.random.choice(indices[i][1]))
indices[i][1].remove(indices[i][2])
sidx = arr.argsort()
b = arr[sidx]
new_vals = np.setdiff1d(np.arange(len(arr)),arr)
arr[sidx[1:][b[:-1] == b[1:]]] = new_vals
for i,x in enumerate(arr):
if x == indices[i][0] and i != indices[i][2]:
arr[i] = arr[indices[i][2]]
arr[indices[i][2]] = x
return arr
样本:
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(arr)
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
arr = np.array([9, 7, 0, 4, 7, 4, 2, 2, 3, 7])
print(create_uniques(arr))
输出:
[9 7 0 4 7 4 2 2 3 7]
[9 7 0 4 6 5 2 1 3 8]
[9 8 0 4 6 5 1 2 3 7]
[9 8 0 4 6 5 2 1 3 7]
[9 7 0 5 6 4 2 1 3 8]