我有两个不同形状的numpy数组,但长度相同(领先维度).我想改变它们中的每一个,使得相应的元素继续对应 - 即相对于它们的前导索引一致地混洗它们.
此代码有效,并说明了我的目标:
def shuffle_in_unison(a, b):
assert len(a) == len(b)
shuffled_a = numpy.empty(a.shape, dtype=a.dtype)
shuffled_b = numpy.empty(b.shape, dtype=b.dtype)
permutation = numpy.random.permutation(len(a))
for old_index, new_index in enumerate(permutation):
shuffled_a[new_index] = a[old_index]
shuffled_b[new_index] = b[old_index]
return shuffled_a, shuffled_b
Run Code Online (Sandbox Code Playgroud)
例如:
>>> a = numpy.asarray([[1, 1], [2, 2], [3, 3]])
>>> b = numpy.asarray([1, 2, 3])
>>> shuffle_in_unison(a, b)
(array([[2, 2],
[1, 1],
[3, 3]]), array([2, 1, 3]))
Run Code Online (Sandbox Code Playgroud)
然而,这种感觉笨重,效率低,而且速度慢,而且需要使阵列的复制 - 我宁愿他们洗牌在原地的,因为他们将是相当大的.
有没有更好的方法来解决这个问题?更快的执行速度和更低的内存使用率是我的主要目标,但优雅的代码也会很好.
我有另外一个想法是:
def shuffle_in_unison_scary(a, b):
rng_state = numpy.random.get_state()
numpy.random.shuffle(a)
numpy.random.set_state(rng_state)
numpy.random.shuffle(b)
Run Code Online (Sandbox Code Playgroud)
这工作...但它是一个有点吓人,因为我看不出有什么保证它会继续工作 - …
好吧,这可能不是最明智的想法,但如果可能,我有点好奇.说我有两个清单:
list1 = [3,2,4,1, 1]
list2 = [three, two, four, one, one2]
Run Code Online (Sandbox Code Playgroud)
如果我运行list1.sort()
,它会对它进行排序,[1,1,2,3,4]
但有没有办法让list2保持同步(所以我可以说第4项属于'3')?我的问题是我有一个非常复杂的程序,可以正常使用列表,但我需要开始引用一些数据.我知道这对于词典来说是一个完美的情况,但我正在努力避免在我的处理中使用字典,因为我确实需要对键值进行排序(如果我必须使用字典,我知道如何使用它们).
基本上这个程序的本质是,数据以随机顺序出现(如上所述),我需要对其进行排序,处理然后发送结果(顺序无关紧要,但用户需要知道哪个结果属于哪个键).我想先将它放在字典中,然后对列表进行排序,但如果不维护订单,我就无法区分具有相同值的项目(在将结果传达给用户时可能会产生影响).理想情况下,一旦我得到列表,我宁愿想出一种方法来将两个列表排序在一起.这可能吗?