我有以下两个数组A和B,
A = [2,6,4,5,3,1]
B = [1,4,3,6,5,2]
我从中形成了一个numpy数组;
oldArr = np.array([[2,6,4,5,3,1],[1,4,3,6,5,2]])
然后,我必须随机选择(例如)3列;
idx = np.random.randint(len(oldArr[0]), size = len(oldArr[0])/2)
这给出了随机数的索引;
array([3, 4, 0])
以及对应的值是;
[[5 3 2]
[6 5 1]]
现在我要像这样构造一个新数组: 我必须将这些随机数保持在同一位置,并以这样的方式交换第0个原始数据和第一个原始数据,即数字不应在新数组中重复,并且必须以相同顺序放置非重复数字。
[2,_,_,5,3,_] # Random number positions didnt change
[1,_,_,6,5,_]
以我的情况进行交换后,必须是这样(我们可以看到原始数据中的数字是唯一的);
[2,1,4,5,3,6]
[1,2,4,6,5,3]
任何人都可以提供一些线索来获取新数组吗?谢谢!
答案 0 :(得分:0)
这是使用遮罩和argsort
的解决方案。假定A
和B
是彼此的混洗。
它按A
中出现的顺序排列B
中的非固定值,反之亦然。
import numpy as np
def reorder(a, b, idx):
ab = np.stack([a, b])
mask = np.ones(a.shape, bool)
mask[idx] = False
aidx, bidx = xidx = ab.argsort(axis=1)
assert np.all(a[aidx] == b[bidx])
xmask = np.empty(ab.shape, bool)
xmask[[[0], [1]], xidx] = mask[xidx[::-1]]
ab[::-1][np.broadcast_to(mask, ab.shape)] = ab[xmask]
return ab
A = np.array([2,6,4,5,3,1])
B = np.array([1,4,3,6,5,2])
idx = np.array([3, 4, 0])
def make(n):
a, b, i = (np.random.permutation(n) for _ in 'xxx')
return a, b, i[:n//2]
def check(a, b, i):
m = np.ones(a.shape, bool)
m[i] = False
result = reorder(a, b, i)
assert np.all(np.sort(result) == np.sort(a))
# warning: expensive!
assert np.all(np.diff(np.where(result[1][m, None]==a)[1]) >= 0)
assert np.all(np.diff(np.where(result[0][m, None]==b)[1]) >= 0)
for a, b, i in [(A, B, idx), make(10), make(20)]:
m = np.zeros(a.shape, int)
m[i] = 1
print(np.stack([a, b, m]), '\n')
print(reorder(a, b, i), '\n')
check(a, b, i)
样品运行(打印3个示例(A,B,蒙版,结果);第一个示例来自OP):
[[2 6 4 5 3 1]
[1 4 3 6 5 2]
[1 0 0 1 1 0]]
[[2 1 4 5 3 6]
[1 2 4 6 5 3]]
[[4 2 1 6 0 7 9 3 8 5]
[1 7 5 3 9 8 2 0 6 4]
[0 1 0 1 1 0 0 1 1 0]]
[[1 2 7 6 0 5 9 3 8 4]
[4 7 2 3 9 1 8 0 6 5]]
[[ 1 4 15 18 6 19 7 13 0 8 5 17 14 12 3 9 2 11 16 10]
[ 0 6 3 1 11 12 4 7 19 10 8 13 9 14 5 17 18 15 16 2]
[ 1 1 0 1 0 0 1 1 0 0 1 1 1 0 1 0 0 0 1 0]]
[[ 1 4 0 18 6 11 7 13 12 19 5 17 14 10 3 8 9 15 16 2]
[ 0 6 15 1 18 19 4 7 17 14 8 13 9 12 5 3 2 11 16 10]]