gpt4 book ai didi

python - 为什么随机抽样与数据集而不是样本量成比例? ( Pandas .sample() 示例)

转载 作者:太空狗 更新时间:2023-10-29 20:51:08 27 4
gpt4 key购买 nike

当我从不同大小的分布中随机抽样时,我惊讶地发现执行时间似乎主要与被抽样的数据集的大小成比例,而不是被抽样的值的数量。示例:

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)))

输出是:

sample 10 from 10000 values: 0.00126 s
sample 10 from 10000000 values: 1.10504 s
sample 1000 from 10000 values: 0.00122 s
sample 1000 from 10000000 values: 1.15000 s

这似乎违反直觉。也许我很密集,但问题似乎类似于生成随机索引列表,而且我希望采样值的数量很重要,而数据集的大小并不重要。我已经尝试了另一种或两种具有类似结果的实现,但我开始觉得我只是遗漏了一个基本问题。

我的问题有两个:(1) 这是一个基本问题还是 pandas 实现的一个怪癖? (2) 是否有一种明显更快的方法可以采用这种方式从大型数据集中随机抽样?

最佳答案

pandas.Series.sample() 在您的案例中归结为:

rs = np.random.RandomState()
locs = rs.choice(axis_length, size=n, replace=False)
return self.take(locs)

慢的部分是rs.choice():

%timeit rs.choice(100000000, size=1, replace=False)
1 loop, best of 3: 9.43 s per loop

生成单个随机数大约需要10秒!如果将第一个参数除以 10,则大约需要 1 秒。太慢了!

如果您使用 replace=True,它会非常快。如果您不介意结果中出现重复条目​​,那么这就是您的一种解决方法。

choice(replace=False) 的 NumPy 文档说:

This is equivalent to np.random.permutation(np.arange(5))[:3]

这几乎可以解释问题——它生成大量可能的值,将它们打乱顺序,然后取前 N 个。这是性能问题的根本原因,并且已在此处作为 NumPy 中的问题报告: https://github.com/numpy/numpy/pull/5158

这显然很难在 NumPy 中修复,因为人们依赖于 choice() 在使用相同的随机种子值时不会改变(在 NumPy 的版本之间)的结果。

由于您的用例非常狭窄,您可以这样做:

def sample(series, n):
locs = np.random.randint(0, len(series), n*2)
locs = np.unique(locs)[:n]
assert len(locs) == n, "sample() assumes n << len(series)"
return series.take(locs)

这提供了更快的时间:

sample 10 from 10000 values: 0.00735 s
sample 10 from 1000000 values: 0.00944 s
sample 10 from 100000000 values: 1.44148 s
sample 1000 from 10000 values: 0.00319 s
sample 1000 from 1000000 values: 0.00802 s
sample 1000 from 100000000 values: 0.01989 s
sample 100000 from 1000000 values: 0.05178 s
sample 100000 from 100000000 values: 0.93336 s

关于python - 为什么随机抽样与数据集而不是样本量成比例? ( Pandas .sample() 示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43011497/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com