Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 随机洗牌numpy数组每行中的项目_Python_Arrays_Numpy - Fatal编程技术网

Python 随机洗牌numpy数组每行中的项目

Python 随机洗牌numpy数组每行中的项目,python,arrays,numpy,Python,Arrays,Numpy,我有一个numpy数组,如下所示: Xtrain = np.array([[1, 2, 3], [4, 5, 6], [1, 7, 3]]) output = np.array([[3, 2, 1], [4, 6, 5], [7, 3, 1]]) 我想分别洗牌每一行的项目,但不希望每一行的洗牌相同(在几个示例中,只是洗牌列顺序) 例如,我希望

我有一个numpy数组,如下所示:

Xtrain = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [1, 7, 3]])
output = np.array([[3, 2, 1],
                   [4, 6, 5],
                   [7, 3, 1]])
我想分别洗牌每一行的项目,但不希望每一行的洗牌相同(在几个示例中,只是洗牌列顺序)

例如,我希望输出如下所示:

Xtrain = np.array([[1, 2, 3],
                   [4, 5, 6],
                   [1, 7, 3]])
output = np.array([[3, 2, 1],
                   [4, 6, 5],
                   [7, 3, 1]])
如何以有效的方式随机洗牌每一行?我的实际np数组超过100000行和1000列。

来自:


由于您只想洗牌列,因此只需对矩阵执行转置操作:

In [86]: np.random.shuffle(Xtrain.T)

In [87]: Xtrain
Out[87]: 
array([[2, 3, 1],
       [5, 6, 4],
       [7, 3, 1]])
注意,在2D数组中,每行洗牌的是行而不是项。i、 e.更改行的位置。因此,如果更改转置矩阵行的位置,实际上就是在对原始数组的列进行洗牌

如果仍然需要完全独立的无序排列,可以为每行创建随机索引,然后使用简单的索引创建最终数组:

In [172]: def crazyshuffle(arr):
     ...:     x, y = arr.shape
     ...:     rows = np.indices((x,y))[0]
     ...:     cols = [np.random.permutation(y) for _ in range(x)]
     ...:     return arr[rows, cols]
     ...: 
演示:


我们可以创建一个随机二维矩阵,按每行对其进行排序,然后使用
argsort
给出的索引矩阵对目标矩阵进行重新排序

target = np.random.randint(10, size=(5, 5))
# [[7 4 0 2 5]
# [5 6 4 8 7]
# [6 4 7 9 5]
# [8 6 6 2 8]
# [8 1 6 7 3]]

shuffle_helper = np.argsort(np.random.rand(5,5), axis=1)
# [[0 4 3 2 1]
# [4 2 1 3 0]
# [1 2 3 4 0]
# [1 2 4 3 0]
# [1 2 3 0 4]]

target[np.arange(shuffle_helper.shape[0])[:, None], shuffle_helper]
# array([[7, 5, 2, 0, 4],
#       [7, 4, 6, 8, 5],
#       [4, 7, 9, 5, 6],
#       [6, 6, 8, 2, 8],
#       [1, 6, 7, 8, 3]])
解释

  • 我们使用
    np.random.rand
    argsort
    来模拟洗牌的效果
  • random.rand
    提供随机性
  • 然后,我们使用
    argsort
    axis=1
    来帮助对每一行进行排序。这将创建可用于重新排序的索引

假设您有一个形状为100000 x 1000的数组
a

b = np.random.choice(100000 * 1000, (100000, 1000), replace=False)
ind = np.argsort(b, axis=1)
a_shuffled = a[np.arange(100000)[:,np.newaxis], ind]

我不知道这是否比循环快,因为它需要排序,但有了这个解决方案,也许你会发明更好的东西,例如用
np.argpartition
而不是
np.argsort
这个解决方案无论如何都是无效的,但我很有兴趣思考它,所以写下来。基本上,您可以展开数组,创建一个行标签数组和一个索引数组。您洗牌索引数组,并用它索引原始数组和行标签数组。然后对行标签应用stableargsort以将数据收集到行中。应用该索引并重塑和中提琴,数据按行独立洗牌:

import numpy as np

r, c = 3, 4  # x.shape

x = np.arange(12) + 1  # Already raveled 
inds = np.arange(x.size)
rows = np.repeat(np.arange(r).reshape(-1, 1), c, axis=1).ravel()

np.random.shuffle(inds)
x = x[inds]
rows = rows[inds]

inds = np.argsort(rows, kind='mergesort')
x = x[inds].reshape(r, c)

这是一个你可以使用的熊猫:

df=pd.数据帧(X_列)
_=df.apply(lambda x:np.random.shuffle(x.values),axis=1,raw=False)
df.values

如果您想洗牌列,请将关键字更改为
axis=0

@Kasramvd根据np文档,多维数组仅沿第一个轴洗牌:
>>>>>arr=np.arange(9)。重塑((3,3))>>np.random.shuffle(arr)>>arr数组([3,4,5],[6,7,8],[0,1,2])
Yes
suffle()
不接受轴参数。这里有一个类似的问题tho@Kasramvd如果我理解的话,这个问题是要改变行顺序,而不是行中的实际值。这比直接排序原始行更好吗?@MadPhysicast直接排序原始行将导致相同的结果,并且不留任何随机性。我刚刚得到了它。您使用的是
argsort
有一个axis参数来补偿
shuffle
的不足。Clever@MadPhysicist确切地谢谢你花时间来理解这个想法。