置换具有混合元素的列表列表(np.random.permutation() 因 ValueError 而失败)

Permute list of lists with mixed elements (np.random.permutation() fails with ValueError)

我正在尝试排列由具有混合类型元素的子列表组成的列表:

import numpy as np

a0 = ['122', 877.503017, 955.471176, [21.701201, 1.315585]]
a1 = ['176', 1134.076908, 1125.504758, [19.436181, 0.9987899]]
a2 = ['177', 1038.686843, 1018.987868, [19.539959, 1.183997]]
a3 = ['178', 878.999081, 1022.050447, [19.6448771, 1.1867719]]

a = [a0, a1, a2, a3]

b = np.random.permutation(a)

这将失败:

ValueError: cannot set an array element with a sequence

是否有内置函数可以让我生成这样的排列?

我需要生成一个随机排列,我并不是要获得所有可能的排列。


我检查了给出的三个答案:

import time
import random

# np.random.permutation()
start = time.time()
for _ in np.arange(100000):
    b = np.random.permutation([np.array(i, dtype='object') for i in a])
print(time.time() - start)

# np.random.shuffle()
start = time.time()
for _ in np.arange(100000):
    b = a[:]
    np.random.shuffle(b)
print(time.time() - start)

# random.shuffle()
start = time.time()
for _ in np.arange(100000):
    random.shuffle(a)
print(time.time() - start)

结果是:

1.47580695152
0.11471414566
0.26300907135

所以 np.random.shuffle() 解决方案比 np.random.permutation() 快 10 倍,比 random.shuffle() 快 2 倍。

您需要将列表转换为 object() 类型的 numpy 数组,以便 random.permutation() 可以将列表解释为 numpy 类型而不是序列:

>>> a = [np.array(i, dtype='object') for i in a]
>>> 
>>> np.random.permutation(a)
array([['122', 877.503017, 955.471176, [21.701201, 1.315585]],
       ['177', 1038.686843, 1018.987868, [19.539959, 1.183997]],
       ['178', 878.999081, 1022.050447, [19.6448771, 1.1867719]],
       ['176', 1134.076908, 1125.504758, [19.436181, 0.9987899]]], dtype=object)

您还可以使用 numpy.array() 从您的列表中创建一个 uniqe 数组,而不是使用列表理解:

>>> a = np.array((a0, a1, a2, a3), dtype='object')
>>> a
array([['122', 877.503017, 955.471176, [21.701201, 1.315585]],
       ['176', 1134.076908, 1125.504758, [19.436181, 0.9987899]],
       ['177', 1038.686843, 1018.987868, [19.539959, 1.183997]],
       ['178', 878.999081, 1022.050447, [19.6448771, 1.1867719]]], dtype=object)
>>> np.random.permutation(a)
array([['122', 877.503017, 955.471176, [21.701201, 1.315585]],
       ['177', 1038.686843, 1018.987868, [19.539959, 1.183997]],
       ['176', 1134.076908, 1125.504758, [19.436181, 0.9987899]],
       ['178', 878.999081, 1022.050447, [19.6448771, 1.1867719]]], dtype=object)
>>> np.random.permutation(a)
array([['177', 1038.686843, 1018.987868, [19.539959, 1.183997]],
       ['176', 1134.076908, 1125.504758, [19.436181, 0.9987899]],
       ['178', 878.999081, 1022.050447, [19.6448771, 1.1867719]],
       ['122', 877.503017, 955.471176, [21.701201, 1.315585]]], dtype=object)

使用 np.random.shuffle 怎么样?

# if you want the result in another list, otherwise just apply shuffle to a
b = a[:]
# shuffle the elements
np.random.shuffle(b)
# see the result of the shuffling
print(b)

shufflepermutation

的区别见this answer

random.shuffle() 更改列表。

Python API 通常就地改变结构的方法 return None.

请尝试random.sample(a,len(a))

代码如下所示:

a = a[:]
b = random.sample(a,len(a))

如果您只想创建 a = [a0, a1, a2, a3] 的随机排列,我是否建议改为排列索引?

>>> random_indices = np.random.permutation(np.arange(len(a)))
>>> a_perm = [a[i] for i in random_indices]
... # Or just use the indices as you see fit...

如果您为此使用 numpy just,请完全跳过 numpy 并仅使用 random.shuffle 来实现相同的效果:

>>> import random
>>> random.shuffle(a)