原始数据:有一列名称为【时长】,描述了1-100s的时间长度,类型为float
需求内容:再增加一列【时长区间】,用于描述【时长】列每个单元格值的区间,结果样式如下
时长 时长区间
0 3.498 [3,4)
1 0.535 (0,1)
2 2.355 [2,3)
3 6.541 [5,8)
4 8.508 [8,10)
现有的代码,当【时长】只有几百或几千行时,执行速度还是挺快的。但实际【时长】数据多达20-50万行,执行时间会非常非常长
import pandas as pd
import time
dict = {
"时长": {
0: 3.498,
1: 0.535,
2: 2.355,
3: 6.541,
4: 8.508,
5: 0.391,
6: 1.254,
7: 0.276,
8: 12.14,
9: 0.827,
10: 1.996,
}
}
df = pd.DataFrame(dict)
df["时长区间"] = 0
time_s = time.perf_counter()
for x, y in enumerate(df["时长"]):
if y < 1:
df.iloc[[x], [1]] = "(0,1)"
elif y < 2:
df.iloc[[x], [1]] = "[1,2)"
elif y < 3:
df.iloc[[x], [1]] = "[2,3)"
elif y < 4:
df.iloc[[x], [1]] = "[3,4)"
elif y < 5:
df.iloc[[x], [1]] = "[4,5)"
elif y < 8:
df.iloc[[x], [1]] = "[5,8)"
elif y < 10:
df.iloc[[x], [1]] = "[8,10)"
else:
df.iloc[[x], [1]] = "[10,~)"
time_e = time.perf_counter()
print(df.head())
print(df.shape)
print("耗时:%s s" % ("%0.2f" % (time_e - time_s)))
上述代码是否还有优化的空间,可以让执行速度更快?尤其是【时长】数据多达20-50万行时,谢谢
用pd.cut()方法,代码如下,如果你的对应关系不一样, 可以修改参数list和labels调整
import pandas as pd
import time
dict = {
"时长": {
0: 3.498,
1: 0.535,
2: 2.355,
3: 6.541,
4: 8.508,
5: 0.391,
6: 1.254,
7: 0.276,
8: 12.14,
9: 0.827,
10: 1.996,
}
}
data = pd.DataFrame(dict)
data['时长区间'] = pd.cut(data['时长'],
[0,1,2,3,4,5,8,10,100], # 数值区间
labels = ['(0-1)','[1,2)','[2,3)','[3,4)','[4,5)','[5,8)','[8,10)','[10,~)'], # 标签
right=False)
没看懂你的时长和区间是怎么个映射关系。不过可以先把时长这一列保存到list中,全部处理完之后再并到detaform中,这样子只要操作一次,速度应该会快很多。
import numpy as np
data['四舍五入时长'] = np.int32(data['时长'])
#以此类推
data['时长区间'] = None
data.loc[data['四舍五入时长']==0,'时长区间'] = '(0,1)'
data.loc[data['四舍五入时长']==1,'时长区间'] = '[1,2)'