202

我有一个非常大的二维数组,看起来像这样:

a=
[[a1, b1, c1],
 [a2, b2, c2],
 ...,
 [an, bn, cn]]

使用 numpy,是否有一种简单的方法可以从初始数组中获取一个新的二维数组,例如 2 个随机行a(无需替换)?

例如

b=
[[a4,  b4,  c4],
 [a99, b99, c99]]
4

9 回答 9

256
>>> 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 之前有一种无需替换即可生成随机列表的好方法。也许您可以设置一个小的定义,以确保两个值不相同。

于 2013-01-10T16:35:09.710 回答
62

这是一个旧帖子,但这是最适合我的:

A[np.random.choice(A.shape[0], num_rows_2_sample, replace=False)]

将 replace=False 更改为 True 以获得相同的结果,但需要替换。

于 2015-01-07T08:37:04.587 回答
32

如果您只想按某个因素对数据进行下采样,另一种选择是创建一个随机掩码。假设我想将原始数据集下采样到 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% 的行,随机抽样。

于 2015-08-03T18:58:14.287 回答
24

这与 Hezi Rasheff 提供的答案相似,但经过简化,以便新的 python 用户了解发生了什么(我注意到许多新的数据科学学生以最奇怪的方式获取随机样本,因为他们不知道自己在 python 中做什么)。

您可以使用以下方法从数组中获取许多随机索引:

indices = np.random.choice(A.shape[0], number_of_samples, replace=False)

然后,您可以对 numpy 数组使用精美的索引来获取这些索引处的样本:

A[indices]

这将从您的数据中获得指定数量的随机样本。

于 2018-12-20T10:35:34.440 回答
5

我看到有人建议排列。其实可以做成一行:

>>> A = np.random.randint(5, size=(10,3))
>>> np.random.permutation(A)[:2]

array([[0, 3, 0],
       [3, 1, 2]])
于 2018-10-19T21:35:49.887 回答
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, :]
于 2018-10-23T11:24:15.353 回答
2

另一种方法是使用类的choice方法Generatorhttps://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方法似乎是最有效的方法,而当您的数组变大时,处理索引是最佳解决方案。

于 2020-10-21T20:50:55.860 回答
1

如果您需要相同的行但只是一个随机样本,那么,

import random
new_array = random.sample(old_array,x)

这里 x, 必须是一个 'int' 定义你想要随机选择的行数。

于 2017-05-16T22:55:10.400 回答
1

可以使用随机数生成器从给定数组生成随机样本:

rng = np.random.default_rng()
b = rng.choice(a, 2, replace=False)
b
>>> [[a4,  b4,  c4],
    [a99, b99, c99]]
于 2021-08-17T08:35:49.317 回答