当从不同大小的分布中随机抽样时,我惊讶地发现执行时间似乎主要是随着数据集的大小而变化的,而不是被采样的值的数量。示例:
import pandas as pd
import numpy as np
import time as tm
#generate a small and a large dataset
testSeriesSmall = pd.Series(np.random.randn(10000))
testSeriesLarge = pd.Series(np.random.randn(10000000))
sampleSize = 10
tStart = tm.time()
currSample = testSeriesLarge.sample(n=sampleSize).values
print('sample %d from %d values: %.5f s' % (sampleSize, len(testSeriesLarge), (tm.time() - tStart)))
tStart = tm.time()
currSample = testSeriesSmall.sample(n=sampleSize).values
print('sample %d from %d values: %.5f s' % (sampleSize, len(testSeriesSmall), (tm.time() - tStart)))
sampleSize = 1000
tStart = tm.time()
currSample = testSeriesLarge.sample(n=sampleSize).values
print('sample %d from %d values: %.5f s' % (sampleSize, len(testSeriesLarge), (tm.time() - tStart)))
tStart = tm.time()
currSample = testSeriesSmall.sample(n=sampleSize).values
print('sample %d from %d values: %.5f s' % (sampleSize, len(testSeriesSmall), (tm.time() - tStart)))
输出为:
^{pr2}$这似乎违反直觉。也许我是稠密的,但问题似乎类似于生成一个随机索引的列表,我本以为采样值的数量和数据集的大小无关紧要。我已经尝试了一两个类似的实现,但是现在开始觉得我忽略了一个基本问题。在
我的问题有两个:(1)这是一个根本问题还是熊猫实施的一个怪癖?(2) 有没有一种更快速的方法可以用这种方法从大数据集中随机抽取样本?在
这似乎是一个内部纽姆问题。我相信pandas
sample
方法调用numpy.random.choice
。让我们看看numpy如何在不同的数组大小和样本大小下执行。在创建数组
在不更换样品的情况下计时
^{pr2}$更换样品计时
非常有趣的是,在不进行替换的情况下,大阵列需要的时间要长近3个数量级,而它的大小正好是3个数量级。这意味着numpy随机地对数组排序,然后取前10项。在
使用替换进行采样时,每个值都是独立选择的,因此计时是相同的。在
pandas.Series.sample()
在您的例子中,可以归结为:慢的部分是
^{pr2}$rs.choice()
:生成一个随机数大约需要10秒!如果你把第一个参数除以10,大约需要1秒。太慢了!在
如果你使用
replace=True
它是超快的。如果您不介意在结果中有重复的条目,这是一个解决方法。在choice(replace=False)
的NumPy文档说明:这就很好地解释了这个问题,它生成了一个巨大的可能值数组,对它们进行洗牌,然后取第一个N。这是性能问题的根本原因,并且已经在NumPy中报告为一个问题:https://github.com/numpy/numpy/pull/5158
显然很难在NumPy中修复,因为当使用相同的随机种子值时,人们依赖于
choice()
不变的结果(在NumPy的不同版本之间)。在由于您的用例非常狭窄,您可以执行以下操作:
这样可以加快速度:
相关问题 更多 >
编程相关推荐