优化我的脚本,计算每周的产品数量
Optimalization of my script whcich calculate weekly qty of product
我有一个任务需要多次更改数据框中的数据。我在 Jupyter notebook 中使用循环写下了答案,大约需要 2.5 分钟才能 运行.
但是,当我使用模块和定义将代码重写为 pycharm 时,大约需要 20 分钟,而且我不知道哪里出错了。
这里是对我的任务和我的想法的解释,是用 Jupyter 写的,也许你会对我如何写得更好有一些想法。
我有一个数据框,其中包含上周 0w 时工厂每周销售的玩具数量。
ID 0w 1w 2w 3w 4w 5w 6w 7w 8w 9w 10w 11w 12w 13w
0 0 1 0 0 5 1 65 2 62 1 1 2 1 60
1 0 0 1 5 16 0 2 0 0 40 0 100 0 0
2 0 3 0 0 0 0 0 40 0 0 20 0 0 0
3 0 5 6 0 0 0 0 0 0 0 0 0 0 0
4 0 1 0 0 0 0 0 0 0 0 0 0 0 0
第一步是将我的 df 中的每一行保存到列表列表 'week_qty':
week_qty = []
lenOfRows = len(copiedData)
for i in range(0, lenOfRows):
week_qty.append(weeksQtyEXTdata.iloc[i])
week_qty[0] = [0 1 0 0 5 1 65 2 62 1 1 2 1 60]
第二步是取每一行的 90% 和 10% 的值,并与列表的每个值进行比较,因此对于第一行,90% = 61.4 和 10% = 0。如果单元格中的值为低于 p10 我将其更改为 p10 的值,如果它高于 p90 我将其更改为 p90 的值。
def CalcPercenatage(week_qty,oneWeek):
p10=np.percentile(weekDemand,10)
p90=np.percentile(weekDemand,90)
if (oneWeek < p10):
return p10
elif(oneWeek > p90):
return p90
else:
return oneWeek
CalcPercenatage(week_qty[0]) = [60, 1, 2, 1, 1, 61.4, 2, 61.4, 1, 5, 0, 0, 1, 0]
最后一步是创建这些值的矩阵,并为一行中的 14 个单元格中的每一个单元格的每一行执行此操作:
for i in range(0, lenOfRows):
Rows = []
for j in range(0, 14):
Rows.append(CalcPercenatage(week_qty[i], week_qty[i][j]))
MatrixBetweenWeeks.append(Rows)
我想让它更快,对于 pycharm 中的 31000 个数据,它工作的时间太长了。
您可以使用 clip
:
p10, p90 = np.percentile(df.iloc[:, 1:], [10, 90], axis=1)
out = df.iloc[:, 1:].clip(p10, p90, axis=0)
out['Average'] = out.mean(axis=1)
out = pd.concat([df.iloc[:, :1], out], axis=1)
输出:
>>> out
ID 0w 1w 2w 3w 4w 5w 6w 7w 8w 9w 10w 11w 12w 13w Average
0 0 0 1.0 0.0 0 5 1 61.4 2.0 61.4 1.0 1.0 2.0 1 60 14.057143
1 1 0 0.0 1.0 5 16 0 2.0 0.0 0.0 32.8 0.0 32.8 0 0 6.400000
2 2 0 3.0 0.0 0 0 0 0.0 14.9 0.0 0.0 14.9 0.0 0 0 2.342857
3 3 0 3.5 3.5 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0.500000
4 4 0 0.0 0.0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0.000000
性能
对于 31K 条记录:
%timeit myfunc(df)
15.3 ms ± 80 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我有一个任务需要多次更改数据框中的数据。我在 Jupyter notebook 中使用循环写下了答案,大约需要 2.5 分钟才能 运行.
但是,当我使用模块和定义将代码重写为 pycharm 时,大约需要 20 分钟,而且我不知道哪里出错了。
这里是对我的任务和我的想法的解释,是用 Jupyter 写的,也许你会对我如何写得更好有一些想法。
我有一个数据框,其中包含上周 0w 时工厂每周销售的玩具数量。
ID 0w 1w 2w 3w 4w 5w 6w 7w 8w 9w 10w 11w 12w 13w
0 0 1 0 0 5 1 65 2 62 1 1 2 1 60
1 0 0 1 5 16 0 2 0 0 40 0 100 0 0
2 0 3 0 0 0 0 0 40 0 0 20 0 0 0
3 0 5 6 0 0 0 0 0 0 0 0 0 0 0
4 0 1 0 0 0 0 0 0 0 0 0 0 0 0
第一步是将我的 df 中的每一行保存到列表列表 'week_qty':
week_qty = []
lenOfRows = len(copiedData)
for i in range(0, lenOfRows):
week_qty.append(weeksQtyEXTdata.iloc[i])
week_qty[0] = [0 1 0 0 5 1 65 2 62 1 1 2 1 60]
第二步是取每一行的 90% 和 10% 的值,并与列表的每个值进行比较,因此对于第一行,90% = 61.4 和 10% = 0。如果单元格中的值为低于 p10 我将其更改为 p10 的值,如果它高于 p90 我将其更改为 p90 的值。
def CalcPercenatage(week_qty,oneWeek):
p10=np.percentile(weekDemand,10)
p90=np.percentile(weekDemand,90)
if (oneWeek < p10):
return p10
elif(oneWeek > p90):
return p90
else:
return oneWeek
CalcPercenatage(week_qty[0]) = [60, 1, 2, 1, 1, 61.4, 2, 61.4, 1, 5, 0, 0, 1, 0]
最后一步是创建这些值的矩阵,并为一行中的 14 个单元格中的每一个单元格的每一行执行此操作:
for i in range(0, lenOfRows):
Rows = []
for j in range(0, 14):
Rows.append(CalcPercenatage(week_qty[i], week_qty[i][j]))
MatrixBetweenWeeks.append(Rows)
我想让它更快,对于 pycharm 中的 31000 个数据,它工作的时间太长了。
您可以使用 clip
:
p10, p90 = np.percentile(df.iloc[:, 1:], [10, 90], axis=1)
out = df.iloc[:, 1:].clip(p10, p90, axis=0)
out['Average'] = out.mean(axis=1)
out = pd.concat([df.iloc[:, :1], out], axis=1)
输出:
>>> out
ID 0w 1w 2w 3w 4w 5w 6w 7w 8w 9w 10w 11w 12w 13w Average
0 0 0 1.0 0.0 0 5 1 61.4 2.0 61.4 1.0 1.0 2.0 1 60 14.057143
1 1 0 0.0 1.0 5 16 0 2.0 0.0 0.0 32.8 0.0 32.8 0 0 6.400000
2 2 0 3.0 0.0 0 0 0 0.0 14.9 0.0 0.0 14.9 0.0 0 0 2.342857
3 3 0 3.5 3.5 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0.500000
4 4 0 0.0 0.0 0 0 0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 0.000000
性能
对于 31K 条记录:
%timeit myfunc(df)
15.3 ms ± 80 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)