Numpy:从2D数组中获取随机行集

时间:2013-01-10 16:30:47

标签: python numpy

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

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

使用numpy,有一种简单的方法可以获得一个新的2D数组,例如来自初始数组a的2个随机行(没有替换)?

e.g。

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

8 个答案:

答案 0 :(得分:147)

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

答案 1 :(得分:37)

这是一篇很老的帖子,但这对我来说最有用:

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

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

答案 2 :(得分:23)

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

答案 3 :(得分:5)

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

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

这里x必须是' int'定义要随机选择的行数。

答案 4 :(得分:4)

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

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

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

然后可以对numpy数组使用切片,以在这些索引处获取样本:

A[indices]

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

答案 5 :(得分:3)

我看到有人建议进行排列。实际上,它可以做成一行:

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

array([[0, 3, 0],
       [3, 1, 2]])

答案 6 :(得分:2)

另一种替代方法是使用choicehttps://github.com/numpy/numpy/issues/10835

Generator方法
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方法在数组较小时似乎是最有效的方法,而在索引上工作时则是数组增大时的最佳解决方案。

答案 7 :(得分:1)

例如,如果要生成多个随机的行子集,例如在执行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, :]