我有一个包含〜200,000行的熊猫数据框,我想创建5行随机样本1000行,但我不希望这些样本中的任何一个包含相同的行两次。熊猫创建没有重复的随机样本
要创建一个随机抽样我一直在使用:
import numpy as np
rows = np.random.choice(df.index.values, 1000)
sampled_df = df.ix[rows]
不过只是做了几次会冒重复的危险。处理此问题的最佳方法是跟踪每次采样哪些行?
我有一个包含〜200,000行的熊猫数据框,我想创建5行随机样本1000行,但我不希望这些样本中的任何一个包含相同的行两次。熊猫创建没有重复的随机样本
要创建一个随机抽样我一直在使用:
import numpy as np
rows = np.random.choice(df.index.values, 1000)
sampled_df = df.ix[rows]
不过只是做了几次会冒重复的危险。处理此问题的最佳方法是跟踪每次采样哪些行?
您可以使用df.sample
设置replace
到False
。
与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)]
可以在np.random.choice
rows = np.random.choice(df.index.values, 1000, replace=False)
看看上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])