2016-05-17 56 views
0

我有一个包含〜200,000行的熊猫数据框,我想创建5行随机样本1000行,但我不希望这些样本中的任何一个包含相同的行两次。熊猫创建没有重复的随机样本

要创建一个随机抽样我一直在使用:

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

不过只是做了几次会冒重复的危险。处理此问题的最佳方法是跟踪每次采样哪些行?

回答

3

您可以使用df.sample设置replaceFalse

与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

可以在np.random.choice

rows = np.random.choice(df.index.values, 1000, replace=False) 
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])