【问题标题】:Drawing a bootstrap sample from a pandas.DataFrame从 pandas.DataFrame 绘制引导样本
【发布时间】:2015-10-08 18:38:14
【问题描述】:

我想尽可能高效地绘制pandas.DataFrame 的引导样本。使用内置 iloc 和整数列表似乎很慢:

import pandas
import numpy as np
# Generate some data
n = 5000
values = np.random.uniform(size=(n, 5))
# Construct a pandas.DataFrame
columns = ['a', 'b', 'c', 'd', 'e']
df = pandas.DataFrame(values, columns=columns)
# Bootstrap
%timeit df.iloc[np.random.randint(n, size=n)]
# Out: 1000 loops, best of 3: 1.46 ms per loop

索引numpy 数组当然要快得多:

%timeit values[np.random.randint(n, size=n)]
# Out: 10000 loops, best of 3: 159 µs per loop

但即使是提取值、对numpy 数组进行采样并构造一个新的pandas.DataFrame 也更快:

%timeit pandas.DataFrame(df.values[np.random.randint(n, size=n)], columns=columns)
# Out: 1000 loops, best of 3: 302 µs per loop

@JohnE 建议 sample 不幸的是更慢:

%timeit df.sample(n, replace=True)
# Out: 100 loops, best of 3: 5.14 ms per loop

@firelynx 建议merge

%timeit df.merge(pandas.DataFrame(index=np.random.randint(n, size=n)), left_index=True, right_index=True, how='right')
# Out: 1000 loops, best of 3: 1.23 ms per loop

有谁知道为什么iloc 这么慢和/或是否有比提取值、采样然后构造一个新的pandas.DataFrame 更好的选择?

【问题讨论】:

  • sample()?自 0.16.1 版起的新功能。 pandas.pydata.org/pandas-docs/stable/whatsnew.html#sample
  • 我添加了您的建议。不幸的是,这甚至更慢。
  • @JohnE,感谢您澄清np.random.randint 花费了大量时间。
  • 什么是columns?您没有在代码中定义它。需要它来重现您的测试。
  • @firelynx,抱歉,有人修改了我的原始帖子。我执行了回滚。

标签: numpy pandas


【解决方案1】:

索引速度

经过测试,布尔索引对我来说稍微快一些:

布尔索引

%timeit -n10000 df[np.random.randint(2, size=n).astype(bool)]
# 10000 loops, best of 3: 307 µs per loop

numpy采样&回复DataFrameing

%timeit -n10000 pandas.DataFrame(df.values[np.random.randint(n, size=n)], columns=columns)
# 10000 loops, best of 3: 380 µs per loop

【讨论】:

  • 这里的问题是布尔索引是没有替换的,而采样应该是替换的。
【解决方案2】:

pandas 中的 merge 方法进行了相当优化,所以我试了一下运气,它给了我显着的速度提升。鉴于我的机器比你的慢一点,我也在使用 pandas 0.15.2 情况可能有点不同。

%timeit df.iloc[np.random.randint(n, size=n)]
# 100 loops, best of 3: 2.41 ms per loop

randlist = pandas.DataFrame(index=np.random.randint(n, size=n))
%timeit df.merge(randlist, left_index=True, right_index=True, how='right')
# 1000 loops, best of 3: 1.87 ms per loop

%timeit df.merge(pandas.DataFrame(index=np.random.randint(n, size=n)), left_index=True, right_index=True, how='right')
# 100 loops, best of 3: 2.29 ms per loop

【讨论】:

    猜你喜欢
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 2017-09-12
    • 2012-02-14
    • 2014-10-06
    • 2011-12-23
    • 2013-07-19
    相关资源
    最近更新 更多