我有一个非常大的二维数组,看起来像这样:
a=
[[a1, b1, c1],
[a2, b2, c2],
...,
[an, bn, cn]]
使用 numpy,是否有一种简单的方法可以从初始数组中获取一个新的二维数组,例如 2 个随机行a
(无需替换)?
例如
b=
[[a4, b4, c4],
[a99, b99, c99]]
>>> A = np.random.randint(5, size=(10,3))
>>> A
array([[1, 3, 0],
[3, 2, 0],
[0, 2, 1],
[1, 1, 4],
[3, 2, 2],
[0, 1, 0],
[1, 3, 1],
[0, 4, 1],
[2, 4, 2],
[3, 3, 1]])
>>> idx = np.random.randint(10, size=2)
>>> idx
array([7, 6])
>>> A[idx,:]
array([[0, 4, 1],
[1, 3, 1]])
将其放在一起用于一般情况:
A[np.random.randint(A.shape[0], size=2), :]
对于非替换(numpy 1.7.0+):
A[np.random.choice(A.shape[0], 2, replace=False), :]
我不相信在 1.7 之前有一种无需替换即可生成随机列表的好方法。也许您可以设置一个小的定义,以确保两个值不相同。
这是一个旧帖子,但这是最适合我的:
A[np.random.choice(A.shape[0], num_rows_2_sample, replace=False)]
将 replace=False 更改为 True 以获得相同的结果,但需要替换。
如果您只想按某个因素对数据进行下采样,另一种选择是创建一个随机掩码。假设我想将原始数据集下采样到 25%,该数据集当前保存在数组中data_arr
:
# generate random boolean mask the length of data
# use p 0.75 for False and 0.25 for True
mask = numpy.random.choice([False, True], len(data_arr), p=[0.75, 0.25])
现在您可以调用data_arr[mask]
并返回约 25% 的行,随机抽样。
这与 Hezi Rasheff 提供的答案相似,但经过简化,以便新的 python 用户了解发生了什么(我注意到许多新的数据科学学生以最奇怪的方式获取随机样本,因为他们不知道自己在 python 中做什么)。
您可以使用以下方法从数组中获取许多随机索引:
indices = np.random.choice(A.shape[0], number_of_samples, replace=False)
然后,您可以对 numpy 数组使用精美的索引来获取这些索引处的样本:
A[indices]
这将从您的数据中获得指定数量的随机样本。
我看到有人建议排列。其实可以做成一行:
>>> A = np.random.randint(5, size=(10,3))
>>> np.random.permutation(A)[:2]
array([[0, 3, 0],
[3, 1, 2]])
如果您想生成多个随机的行子集,例如,如果您正在执行 RANSAC。
num_pop = 10
num_samples = 2
pop_in_sample = 3
rows_to_sample = np.random.random([num_pop, 5])
random_numbers = np.random.random([num_samples, num_pop])
samples = np.argsort(random_numbers, axis=1)[:, :pop_in_sample]
# will be shape [num_samples, pop_in_sample, 5]
row_subsets = rows_to_sample[samples, :]
另一种方法是使用类的choice
方法Generator
,https://github.com/numpy/numpy/issues/10835
import numpy as np
# generate the random array
A = np.random.randint(5, size=(10,3))
# use the choice method of the Generator class
rng = np.random.default_rng()
A_sampled = rng.choice(A, 2)
导致采样数据,
array([[1, 3, 2],
[1, 2, 1]])
运行时间也被分析比较如下,
%timeit rng.choice(A, 2)
15.1 µs ± 115 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.random.permutation(A)[:2]
4.22 µs ± 83.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit A[np.random.randint(A.shape[0], size=2), :]
10.6 µs ± 418 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但是当数组变大时,A = np.random.randint(10, size=(1000,300))
. 处理索引是最好的方法。
%timeit A[np.random.randint(A.shape[0], size=50), :]
17.6 µs ± 657 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit rng.choice(A, 50)
22.3 µs ± 134 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.random.permutation(A)[:50]
143 µs ± 1.33 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
因此,当您的数组较小时,该permutation
方法似乎是最有效的方法,而当您的数组变大时,处理索引是最佳解决方案。
如果您需要相同的行但只是一个随机样本,那么,
import random
new_array = random.sample(old_array,x)
这里 x, 必须是一个 'int' 定义你想要随机选择的行数。
可以使用随机数生成器从给定数组生成随机样本:
rng = np.random.default_rng()
b = rng.choice(a, 2, replace=False)
b
>>> [[a4, b4, c4],
[a99, b99, c99]]