Pandas创建随机样本而不重复

时间:2016-05-17 17:40:39

标签: python pandas

我有一个包含~200,000行的pandas数据帧,我想创建5个随机样本,每行1000行,但我不希望这些样本中的任何一行包含两次相同的行。

要创建我一直在使用的随机样本:

import numpy as np
rows = np.random.choice(df.index.values, 1000)
sampled_df = df.ix[rows]

然而,这样做几次会冒重复的风险。处理此问题的最佳方法是跟踪每次采样的行数吗?

3 个答案:

答案 0 :(得分:4)

您可以使用df.sample

包含100行和5列的数据框:

df = pd.DataFrame(np.random.randn(100, 5), columns = list("abcde"))

示例5行:

df.sample(5)
Out[8]: 
           a         b         c         d         e
84  0.012201 -0.053014 -0.952495  0.680935  0.006724
45 -1.347292  1.358781 -0.838931 -0.280550 -0.037584
10 -0.487169  0.999899  0.524546 -1.289632 -0.370625
64  1.542704 -0.971672 -1.150900  0.554445 -1.328722
99  0.012143 -2.450915 -0.718519 -1.192069 -1.268863

这确保了这5行不同。如果您想重复此过程,我建议您对number_of_rows * number_of_samples行进行抽样。例如,如果每个样本将包含5行,并且您需要10个样本,则样本50行。前5个将是第一个样本,第二个将是第二个......

all_samples = df.sample(50)
samples = [all_samples.iloc[5*i:5*i+5] for i in range(10)]

答案 1 :(得分:2)

您可以在replace

中将False设置为np.random.choice
rows = np.random.choice(df.index.values, 1000, replace=False)

答案 2 :(得分:2)

查看numpy.random文档

为您的解决方案:

import numpy as np
rows = np.random.choice(df.index.values, 1000, replace=False)
sampled_df = df.ix[rows]

这将随机选择而无需替换。

如果要生成多个样本,没有任何元素可以共同使用,则需要在每次迭代后从每个选项中删除元素。您可以使用numpy.setdiff1d

import numpy as np
allRows = df.index.values
numOfSamples = 5
samples = list()

for i in xrange(numOfSamples):
    choices = np.random.choice(allRows, 1000, replace=False)
    samples.append(choices)
    allRows = np.setdiff1d(allRows, choices)

以下是一个工作示例,其范围为0到100之间的数字:

In [58]: import numpy as np
In [59]: allRows = np.arange(100)
In [60]: numOfSamples = 5
In [61]: samples = list()
In [62]: for i in xrange(numOfSamples):
   ....:     choices = np.random.choice(allRows, 5, replace=False)
   ....:     samples.append(choices)
   ....:     allRows = np.setdiff1d(allRows, choices)
   ....:

In [63]: samples
Out[63]:
[array([66, 24, 47, 31, 22]),
 array([ 8, 28, 15, 62, 52]),
 array([18, 65, 71, 54, 48]),
 array([59, 88, 43,  7, 85]),
 array([97, 36, 55, 56, 14])]

In [64]: allRows
Out[64]:
array([ 0,  1,  2,  3,  4,  5,  6,  9, 10, 11, 12, 13, 16, 17, 19, 20, 21,
       23, 25, 26, 27, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 44,
       45, 46, 49, 50, 51, 53, 57, 58, 60, 61, 63, 64, 67, 68, 69, 70, 72,
       73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 89, 90, 91,
       92, 93, 94, 95, 96, 98, 99])