我有一个如下所示的numpy数组:
import 'package:flutter/material.dart';
void main() {
runApp(
new MyApp(),
);
}
class MyApp extends StatefulWidget {
const MyApp({
Key key,
}) : super(key: key);
@override
MyAppState createState() {
return new MyAppState();
}
}
class MyAppState extends State<MyApp> {
MaterialColor _color = Colors.green;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Hello Rectangle',
home: Scaffold(
appBar: AppBar(
title: Text('Hello Rectangle'),
),
body: Column(children: <Widget>[
HelloRectangle(_color),
FlatButton(
child: Text(
_color == Colors.green ? "Turn Blue" : "Turn Green",
style: TextStyle(fontSize: 40.0),
textAlign: TextAlign.center,
),
onPressed: () {
setState(() {
_color = _color == Colors.green ? Colors.blue : Colors.green;
});
},
),
]),
),
);
}
}
class HelloRectangle extends StatefulWidget {
final Color color;
HelloRectangle(this.color);
@override
HelloRectangleState createState() {
return new HelloRectangleState();
}
}
class HelloRectangleState extends State<HelloRectangle> {
HelloRectangleState();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: widget.color,
height: 400.0,
width: 300.0,
),
);
}
}
我想分别对每行的项进行随机播放,但不希望每行的shuffle相同(如在几个示例中只是随机播放列顺序)。
例如,我想要一个如下输出:
Xtrain = np.array([[1, 2, 3],
[4, 5, 6],
[1, 7, 3]])
如何以有效的方式随机随机地随机播放每一行?我的实际np数组超过100000行和1000列。
答案 0 :(得分:6)
由于您只想对列进行随机播放,因此只需对矩阵的转置执行shuffling即可:
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]
...:
请注意,2D阵列上的random.suffle()会混洗行而不是每行中的项目。即改变行的位置。因此,如果你改变转置矩阵行的位置,你实际上是在改组原始数组的列。
如果你仍然需要一个完全独立的shuffle,你可以为每一行创建随机索引,然后使用简单的索引创建最终数组:
In [173]: crazyshuffle(Xtrain)
Out[173]:
array([[1, 3, 2],
[6, 5, 4],
[7, 3, 1]])
In [174]: crazyshuffle(Xtrain)
Out[174]:
array([[2, 3, 1],
[4, 6, 5],
[1, 3, 7]])
演示:
FIND
答案 1 :(得分:3)
这种解决方案无论如何都没有效率,但我很乐意考虑它,所以写下来。基本上,您对数组进行了ravel,并创建了一个行标签数组和一个索引数组。您将索引数组混洗,并使用该数组索引原始和行标签数组。然后,将稳定 argsort应用于行标签,以将数据收集到行中。应用该索引和重塑和中提琴,数据由行独立混洗:
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)
答案 2 :(得分:2)
来自:https://github.com/numpy/numpy/issues/5173
def disarrange(a, axis=-1):
"""
Shuffle `a` in-place along the given axis.
Apply numpy.random.shuffle to the given axis of `a`.
Each one-dimensional slice is shuffled independently.
"""
b = a.swapaxes(axis, -1)
# Shuffle `b` in-place along the last axis. `b` is a view of `a`,
# so `a` is shuffled in place, too.
shp = b.shape[:-1]
for ndx in np.ndindex(shp):
np.random.shuffle(b[ndx])
return
答案 3 :(得分:2)
我们可以创建一个随机的二维矩阵,按行排序,然后使用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
来帮助对每一行进行排名。这将创建可用于重新排序的索引。答案 4 :(得分:1)
假设您有阵列a
,其形状为100000 x 1000.
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
答案 5 :(得分:0)
您可以使用Pandas
:
df = pd.DataFrame(X_train)
_ = df.apply(lambda x: np.random.shuffle(x.values), axis=1, raw=False)
df.values
如果要随机排列列,请将关键字更改为axis=0
。
答案 6 :(得分:0)
现在规范的方法是使用random generator的permutation()
方法。
generator = np.random.default_rng(seed=123)
generator.permutation(Xtrain, axis=1)
array([[1, 3, 2],
[4, 6, 5],
[1, 3, 7]])