我有一个包含~200,000行的pandas数据帧,我想创建5个随机样本,每行1000行,但我不希望这些样本中的任何一行包含两次相同的行。
要创建我一直在使用的随机样本:
import numpy as np
rows = np.random.choice(df.index.values, 1000)
sampled_df = df.ix[rows]
然而,这样做几次会冒重复的风险。处理此问题的最佳方法是跟踪每次采样的行数吗?
答案 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])