【发布时间】:2020-04-24 04:18:02
【问题描述】:
我正在尝试加速下面的代码,该代码会为每列生成一个具有不同类型的列表列表。我最初创建了 pandas 数据框,然后将其转换为列表,但这似乎相当慢。我怎样才能更快地创建这个列表,比如说一个数量级?除了一列之外,所有列都是不变的。
import pandas as pd
import numpy as np
import time
import datetime
def overflow_check(x):
# in SQL code the column is decimal(13, 2)
p=13
s=3
max_limit = float("9"*(p-s) + "." + "9"*s)
#min_limit = 0.01 #float("0" + "." + "0"*(s-2) + '1')
#min_limit = 0.1
if np.logical_not(isinstance(x, np.ndarray)) or len(x) < 1:
raise Exception("Non-numeric or empty array.")
else:
#print(x)
return x * (np.abs(x) < max_limit) + np.sign(x)* max_limit * (np.abs(x) >= max_limit)
def list_creation(y_forc):
backcast_length = len(y_forc)
backcast = pd.DataFrame(data=np.full(backcast_length, 2),
columns=['TypeId'])
backcast['id2'] = None
backcast['Daily'] = 1
backcast['ForecastDate'] = y_forc.index.strftime('%Y-%m-%d')
backcast['ReportDate'] = pd.to_datetime('today').strftime('%Y-%m-%d')
backcast['ForecastMethodId'] = 1
backcast['ForecastVolume'] = overflow_check(y_forc.values)
backcast['CreatedBy'] = 'test'
backcast['CreatedDt'] = pd.to_datetime('today')
return backcast.values.tolist()
i=pd.date_range('05-01-2010', '21-05-2018', freq='D')
x=pd.DataFrame(index=i, data = np.random.randint(0, 100, len(i)))
t=time.perf_counter()
y =list_creation(x)
print(time.perf_counter()-t)
【问题讨论】:
-
我建议返回
backcast数据框,然后应用values.tolist()。这样你就可以更好地测试瓶颈在哪里。我对pandas没有足够的经验来判断什么是慢的。但似乎您一次创建一个框架Series,这似乎是合理的。直接构建列表需要迭代整个时间,一次构建一个子列表。我猜这将很难扩展。 -
混合使用 dtypes(数据框列),
backcast.to_records().tolist()转换可能会让您更满意,但这只是猜测。 -
@hpaulj 在性能上似乎相似。我猜是一一列添加导致了这个问题。
标签: python python-3.x pandas list numpy