洗牌与排列numpy的区别

103
numpy.random.shuffle(x)numpy.random.permutation(x)有什么区别?
我已经阅读了文档页面,但无法确定两者之间是否有任何区别,如果我只想随机打乱数组的元素。更确切地说,假设我有一个数组x=[1,4,2,8]
如果我想生成x的随机排列,那么在shuffle(x)permutation(x)之间有什么区别?
4个回答

135

np.random.permutationnp.random.shuffle有两个不同之处:

  • 如果传递一个数组,它将返回数组的一个洗牌后的副本np.random.shuffle会就地对数组进行洗牌。
  • 如果传递一个整数,它将返回一个打乱顺序的范围,即np.random.shuffle(np.arange(n))

如果x是一个整数,则随机置换np.arange(x)。如果x是一个数组,则复制并随机打乱元素。

源代码可能有助于理解这一点:

3280        def permutation(self, object x):
...
3307            if isinstance(x, (int, np.integer)):
3308                arr = np.arange(x)
3309            else:
3310                arr = np.array(x)
3311            self.shuffle(arr)
3312            return arr

2
当在 panda.Index 上使用时,只有 permutation 起作用,而 shuffle 不起作用。这种情况如何符合您的解释? - Heisenberg
1
@Heisenberg permutation 强制将其参数转换为 ndarray(通过复制);pandas.Index 与 ndarray 的区别足够大,以至于 shuffle 无法在其中运行,但可以在由此创建的 ndarray 上运行。 - ecatmur

37

继@ecatmur所说的添加,np.random.permutation在需要对有序配对进行洗牌时非常有用,特别是在分类方面:

from np.random import permutation
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target

# Data is currently unshuffled; we should shuffle 
# each X[i] with its corresponding y[i]
perm = permutation(len(X))
X = X[perm]
y = y[perm]

1
我一直收到这个错误:TypeError: 只有整数标量数组才能转换为标量索引。 - john k
2
澄清一下@hlin117,这只适用于x和y是numpy数组的情况。如果您尝试使用Python内置列表执行此操作,它将抛出TypeError异常。 - benjaminjsanders

3
permutation() 方法返回重新排列的数组(原始数组不变),该方法将保持原始数组完好无损,并返回一个打乱顺序的数组,例如 x = [1,4,2,8] 是原始数组,permutation 方法将返回重新排列的数组(假设为 [8,4,1,2])。现在,您有两个数组,原始数组和重新排列的数组。
另一方面,
shuffle() 方法会更改原始数组,例如 x = [1,4,2,8] 是原始数组,shuffle 方法将返回打乱顺序的数组(假设打乱后的数组是 [8,4,1,2])。现在,原始数组本身已经被更改为打乱顺序的数组,您只剩下打乱顺序的数组。
参考资料:-https://www.w3schools.com/python/numpy_random_permutation.asp

1

在@ecatmur的基础上,这里是一个简短的解释。首先,我创建了一个数组,其形状为3,3,包含从0到8的数字。

import numpy as np
x1 = np.array(np.arange(0,9)).reshape(3,3) #array with shape 3,3 and have numbers from 0 to 8

#step1: using np.random.permutation
x_per = np.random.permutation(x1)
print('x_per:', x_per)
print('x_1:', x_1)
#Inference: x1 is not changed and x_per has its rows randomly changed

#The outcome will be 
x1: [[0 1 2]
     [3 4 5]
     [6 7 8]]
x_per:[[3 4 5]
       [0 1 2]
       [6 7 8]]
#Lets apply shuffling
x2 = np.array(range(9)).reshape(3,3)
x2_shuffle = np.random.shuffle(x2)
print('x2_shuffle:', x2_shuffle)
print('x2', x2)

#Outcome: 
x2_shuffle: None
x2 [[3 4 5]
    [0 1 2]
    [6 7 8]]

关键推断是:当x是一个数组时,numpy.random.permutation(x)和numpy.random.shuffle(x)都可以沿着第一轴随机地排列x中的元素。numpy.random.permutation(x)实际上返回一个新变量,原始数据不会改变。而numpy.random.shuffle(x)已经改变了原始数据,没有返回一个新的变量。我只是试图用一个例子来说明,这样可以帮助其他人。谢谢!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接