python – pandas range_date极其缓慢地降低了功能
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – pandas range_date极其缓慢地降低了功能,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3744字,纯文字阅读大概需要6分钟。
内容图文
我给出了一个样本数据集,并希望从原始样本数据集中选择多个样本,例如1000个样本块,每个样本块包含来自原始样本数据的500个数据点.我在python中写了这个小函数:
import timeit
import pandas as pd
import numpy as np
sample_data = np.random.randn(10000, 15)
index = pd.date_range("20000101", periods=10000, freq='B')
sample_data_df = pd.DataFrame(sample_data, index=index)
def f(n, sample_data_df, f):
s = (1+sample_data_df).resample(f, axis=0)
r = s.prod()-1
out = r.sample(n, replace=True)
# out_index = pd.date_range(start=sample_data_df.index[0],
# periods=len(out.index),
# freq=f)
# out.index = output_index
return out
start_time = timeit.default_timer()
N = 1000
a = [f(500, sample_data_df, 'BM') for i in range(N)]
elapsed = timeit.default_timer() - start_time
print(elapsed)
如果我运行此代码,则需要35.8964748383秒.但是,我想在每个块上附加一个索引,我将取消注释函数中的行,即
def f(n, sample_data_df, f):
s = (1+sample_data_df).resample(f, axis=0)
r = s.prod()-1
out = r.sample(n, replace=True)
out_index = pd.date_range(start=sample_data_df.index[0],
periods=len(out.index),
freq=f)
out.index = output_index
return out
现在该功能需要72.2418179512.疯了吧.如果需要在每个输出中都有这样的索引,我怎样才能加快这个速度?我知道生成一次索引并将其随后附加到每个输出.但是,我想在其他情况下使用该函数,以便在索引的分配在函数内完成时将非常感激.
此外,除了索引还有其他来源可以提高速度吗?因为即使没有索引35.8964748383也是很长时间.
解决方法:
编辑:
>添加了创建新日期索引的时间
>添加了缓存函数以创建新索引
问题不在于重新采样或索引的速度,如果我们看一下时间:
%timeit (1+sample_data_df).resample('BM', axis=0).prod()-1
21.7 ms ± 170 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit pd.date_range(start="20000101", periods=500, freq='BM')
21.4 ms ± 272 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)
考虑到我们正在对150’000元素进行重新采样和减少,22 ms对我来说似乎并不坏.
你的问题来自1000,这在你的情况下是没有必要的(因为你做的完全相同).
如果要在函数中保留重新采样,可以执行的操作是缓存重新采样的结果.不幸的是,缓存函数结果(lru_cache)的标准方法是无法处理可变对象(如dfs,lists ……).所以我的解决方案是将重新采样包装在一个创建哈希的函数中,并以哈希作为参数调用实际函数:
from functools import lru_cache
class Sampler():
def __init__(self, df):
self.df = df
def get_resampled_sample(self, n, freq):
resampled = self._wraper_resample_prod(freq)
return resampled.sample(n, replace=True)
def _wraper_resample_prod(self, freq):
hash_df = hash(self.df.values.tobytes())
return self._resample_prod(hash_df, freq)
@lru_cache(maxsize=1)
def _resample_prod(self, hash_df, freq):
return (self.df+1).resample(freq, axis=0).prod()-1
现在,只要不更改df值的哈希值,就会缓存重新采样的结果.这意味着我们可以更快地采样.
%timeit [sampler.get_resampled_sample(500, 'BM') for i in range(1000)]
881 ms ± 10.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
您可以对索引执行相同的操作,但是在这里您不需要创建自定义哈希,因为pd.date_range的所有参数都是不可变对象.
class Sampler():
def __init__(self, df):
self.df = df
def update_df(self, df):
self.df = df
def get_resampled_sample(self, n, freq):
resampled = self._wraper_resample_prod(freq)
df = resampled.sample(n, replace=True)
df.index = self._create_date_range(self.df.index[0], n, freq)
return df
def _wraper_resample_prod(self, freq):
hash_df = hash(self.df.values.tobytes())
return self._resample_prod(hash_df, freq)
@lru_cache(maxsize=1)
def _resample_prod(self, hash_df, freq):
return (self.df+1).resample(freq, axis=0).prod()-1
@lru_cache(maxsize=1)
def _create_date_range(self, start, periods, freq):
return pd.date_range(start=start, periods=periods, freq=freq)
时序:
%timeit [sampler.get_resampled_sample(500, 'BM') for i in range(1000)]
1.11 s ± 43.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
内容总结
以上是互联网集市为您收集整理的python – pandas range_date极其缓慢地降低了功能全部内容,希望文章能够帮你解决python – pandas range_date极其缓慢地降低了功能所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。