Python 使用阵列/其他方法进行优化
我有这段代码,主要用于预测预测值/实际值(一个部门生产的单位),预测值是从一个文件夹中提取的,其中有100个标记为1-100的csv文件。我告诉程序返回之前的文件,并将其与实际生成的值(在basefile/baseheader中给出)进行比较。基本上,每个文件都有当前月份生成的实际单位,然后有12个月的预测。我用这个程序来计算它,但是它运行得很慢。当我指定的范围较大时,图形显示需要30秒以上的时间,但是如果我只是看到几个月的范围,它会非常快。有人告诉我,我需要更改代码中表示onetotal、twototal、threetotal等的部分,并将它们更改为数组。但是,我不确定如何进行这项工作,我也不知道以后如何绘制精确的值(因为我需要绘制一个总数,然后绘制两个总数,等等(然后显示一个Totalist、两个Totalist的值的分布),关于如何处理这个问题以加快程序的速度,有什么想法吗Python 使用阵列/其他方法进行优化,python,pandas,csv,Python,Pandas,Csv,我有这段代码,主要用于预测预测值/实际值(一个部门生产的单位),预测值是从一个文件夹中提取的,其中有100个标记为1-100的csv文件。我告诉程序返回之前的文件,并将其与实际生成的值(在basefile/baseheader中给出)进行比较。基本上,每个文件都有当前月份生成的实际单位,然后有12个月的预测。我用这个程序来计算它,但是它运行得很慢。当我指定的范围较大时,图形显示需要30秒以上的时间,但是如果我只是看到几个月的范围,它会非常快。有人告诉我,我需要更改代码中表示onetotal、tw
import csv
import pandas as pd
import matplotlib.pyplot as plt
# Beginning part of code is user input and calcultions to determine the Department,Range, and there is a function called getfileheader
def nmonthaccuracy(basefilenumber, n):
basefileread = pd.read_csv(str(basefilenumber) + ".csv", encoding="Latin-1")
baseheader = getfileheader(basefilenumber)
basefilevalue = basefileread.loc[
basefileread["Customer"].str.contains(Department, na=False), baseheader
]
nmonthread = pd.read_csv(str(basefilenumber - n) + ".csv", encoding="Latin-1")
nmonthvalue = nmonthread.loc[
nmonthread["Customer"].str.contains(Department, na=False), baseheader
]
return (
(1 - (int(basefilevalue) / int(nmonthvalue)) + 1)
if int(nmonthvalue) > int(basefilevalue)
else int(nmonthvalue) / int(basefilevalue)
)
N = 13
total = [0] * N
total_by_month_list = [[] for _ in range(N)]
for basefilenumber in range(int(StartRange), int(EndRange)):
for n in range(N):
total[n] += nmonthaccuracy(basefilenumber, n)
total_by_month_list[n].append(nmonthaccuracy(basefilenumber, n))
onetotal=total[1]/ Range
twototal=total[2]/ Range
threetotal=total[3]/ Range
fourtotal=total[4]/ Range
fivetotal=total[5]/ Range
sixtotal=total[6]/ Range
seventotal=total[7]/ Range
eighttotal=total[8]/ Range
ninetotal=total[9]/ Range
tentotal=total[10]/ Range
eleventotal=total[11]/ Range
twelvetotal=total[12]/ Range
onetotallist=total_by_month_list[1]
twototallist=total_by_month_list[2]
threetotallist=total_by_month_list[3]
fourtotallist=total_by_month_list[4]
fivetotallist=total_by_month_list[5]
sixtotallist=total_by_month_list[6]
seventotallist=total_by_month_list[7]
eighttotallist=total_by_month_list[8]
ninetotallist=total_by_month_list[9]
tentotallist=total_by_month_list[10]
eleventotallist=total_by_month_list[11]
twelvetotallist=total_by_month_list[12]
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
y = [
onetotal,
twototal,
threetotal,
fourtotal,
fivetotal,
sixtotal,
seventotal,
eighttotal,
ninetotal,
tentotal,
eleventotal,
twelvetotal,
]
z = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
w = [
(onetotallist),
(twototallist),
(threetotallist),
(fourtotallist),
(fivetotallist),
(sixtotallist),
(seventotallist),
(eighttotallist),
(ninetotallist),
(tentotallist),
(eleventotallist),
(twelvetotallist),
]
fig, ax = plt.subplots()
for ze, we in zip(z, w):
plt.scatter([ze] * len(we), we, marker="D", s=5)
plt.xlabel("Number of months forecast")
plt.ylabel("Predicted/Actual ratio")
plt.title("Predicted to actual ratio for n month forecast")
ax.plot(x, y, label="Predicted/Actual")
for a, b in zip(x, y):
plt.text(a, b, str(round(b, 2)))
plt.scatter(x, y)
plt.show()
这是一个虚拟csv文件:
和我的图表(如果好奇的话)
好的,有几件事:
- 您读取每个文件24次(每个N读取两次)
- 在生成x/y/z/w时存在不必要的重复
- 使用lru_缓存装饰器确保每个文件只读取一次(并保存在内存中;如果出现问题,可以限制lru缓存的大小--请参阅文档)
- 对列表(0..11)使用基于零的索引;这是Python的惯用法
您已经有了
total
和total\u by\u month\u列表
。。。为什么您还需要这些额外的…total
和…totalist
变量?@AKX,因为我使用这些变量并绘制它们来生成我显示的图形,除非有另一种我不知道的方法可以这样做?您不必从列表中提取变量来将它们用于图形。介意添加您省略的Matplotlib代码吗?:)@好的,我加进去了!好的,谢谢。让我看看……哇,看起来棒极了!谢谢你的解释。让我试着在我的代码中实现它,我会让你知道它是如何运行的!:)我的图表现在立即出现!非常感谢你。这也是一次很棒的学习经历,因为我不知道代码中的functools部分。再次感谢你!嗨,我的程序的下一部分实际上要求我对变量进行等式运算,比如我设置为一个整数的变量。这段代码有没有办法仍然设置一个总值,这样我就可以进行这样的计算:一个总值调整=一个总值*1.2?您可以使用列表理解来调整整个数组:adjusted=[value*1.2 for value in total]
。这样就没有办法单独进行了?因为我必须对每一个都有不同的方程式(一个总数可能乘以1.2,其中两个总数可能乘以1.5,依此类推)
import functools
import pandas as pd
import matplotlib.pyplot as plt
Department = ...
Range = ...
StartRange = ...
EndRange = ...
# The lru_cache decorator will ensure each file is read into memory only once (and kept there)
@functools.lru_cache()
def read_file(n):
return pd.read_csv(str(n) + ".csv", encoding="Latin-1")
def nmonthaccuracy(basefilenumber, n):
basefileread = read_file(basefilenumber)
baseheader = getfileheader(basefilenumber)
basefilevalue = basefileread.loc[
basefileread["Customer"].str.contains(Department, na=False), baseheader
]
nmonthread = read_file(basefilenumber - n)
nmonthvalue = nmonthread.loc[
nmonthread["Customer"].str.contains(Department, na=False), baseheader
]
return (
(1 - (int(basefilevalue) / int(nmonthvalue)) + 1)
if int(nmonthvalue) > int(basefilevalue)
else int(nmonthvalue) / int(basefilevalue)
)
N = 12
total_by_month_list = [[] for _ in range(N)]
for basefilenumber in range(int(StartRange), int(EndRange)):
for n in range(N):
# note "n+1" below since n is now zero-indexed
total_by_month_list[n].append(nmonthaccuracy(basefilenumber, n + 1))
total = [sum(by_month) for by_month in total_by_month_list]
x = list(range(1, N + 1)) # [1..12]
y = [t / Range for t in total]
z = x # same as x
w = total_by_month_list
# ... matplotlib code ...