我有一项任务,需要多次更改数据帧中的数据。我把答案写在Jupyter笔记本上,使用循环,大约需要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)