鱼C论坛

 找回密码
 立即注册
查看: 1159|回复: 7

如何优化如下代码,以提高运行速度

[复制链接]
发表于 2019-5-29 14:38:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
遇到个代码优化的问题。。想请教下。。这段代码,结构或是哪里该如何优化下,以提高运行速度。。
大致情况先介绍下:
1. 代码需要考虑指定文件的输出---也就是相应数据是否需要计算;代码中的if output1 / output2 in condition,即是用来判断是否需要进行计算;(其实就是第2点描述的两种情况输出)
2.  数据量是10W行,为时间记录数据。。分两种情况进行计算(也就是两种情况的结果输出)。一种是每行时间数据,均要输出一个结果。另一种是对某个字段进行分组,然后根据分组来输出计算结果(比如企业)。
3. 计算需要分步骤进行。大致是先根据原始数据,计算原始数据的x1值(该步骤已经执行)。再根据x1值,计算相应的x1x2值,和x3值。然后将x1x2和x3拼接起来。
4.  跑这段代码,我这边大概运行了25秒左右。。个人觉得代码写得比较乱,自身水平也有限。。因此,特地来此请各位大神帮忙。。看能否提高速度。。
我的具体代码如下:
  1. t05 = time.time()
  2. #计算x1x2和x3的值(x1值已计算出来)
  3. for i in std_level:
  4.     max_std,min_std,l_1,l_2,l_3,l_4,l_5 = std_level[i][0]  #生成标准的数据表,用于对照取值
  5.     #对原x1的字段的空值填充为0,方便跳过数值0进行数据处理。同时便于后期与目标值比较。
  6.     if output1 in condition: #这个情况,是根据用户需求,进行相应的输出。如用户有需求,则执行下面的代码
  7.         data['%s_x1'%i].fillna(0,inplace =True)
  8.     if output2 in condition:
  9.         f_data['%s_x1'%i].fillna(0,inplace =True)
  10.     #定义x1x2的函数
  11.     #x1为原始数据对应的等级,值为1--6(如原数据缺失,则为空值。为便于判断,需将x1的缺失值填充为0)
  12.     #原则是,如x1(数据等级)为空值,则不进行判定(返回空值)。如等级为1或6,单独计算。如等级介于1和6之间,则统一计算。
  13.     def tran_x1x2(x):
  14.         dj = x['%s_x1'%i]
  15.         jc = x[i]
  16.         if dj == 0:
  17.             return np.NaN  #务必要返回np.NaN,否则返回空字符串None,影响后面x2的计算。
  18.         else:
  19.             if dj not in [1,6]: #根据介于等级1和6之间时的x1x2的计算公式
  20.                 up = std_level[i][0][int(dj)]
  21.                 dn = std_level[i][0][int(dj)+1]
  22.                 return round(dj + (up - jc) / (up -dn),1)
  23.             else:
  24.                 if dj == 1:
  25.                     return 1.0
  26.                 else:
  27.                     return round(dj + (l_5 - jc) / l_5 * 4,1)
  28.     #需事先定义好x1x2的函数,方能进行apply。而x1x2的函数定义,又需要事先对x1填充。。所以需要将条件判断,分开两次重复进行
  29.     #本来考虑可以将条件判断合并到一起。。但是这样会增加重复的代码量,而且不能保证提高速度。
  30.     #我也想用函数的方式来处理,但是不知道如何实现。。具体结构该怎么弄。。。
  31.     if output1 in condition:  
  32.         data['%s_x1x2'%i] = data.apply(tran_x1x2,axis=1)  #生成实时数据的x1x2
  33.     if output2 in condition:
  34.         f_data['%s_x1x2'%i] = f_data.apply(tran_x1x2,axis=1) #生成综合数据的x1x2
  35.     #注意顺序,需先计算x1x2的值,才能计算x3的值
  36.     def tran_x3(x):
  37.         dj = x['%s_x1'%i]
  38.         dj_x1x2 = x['%s_x1x2'%i]
  39.         dj_x2 = (dj_x1x2 - dj) *10  #计算x2的值。不建议单独生成x2字段,否则字段过多,影响调试查看。
  40.         if dj == 0: #等级数据不可能为0,其值原为空值,只是为了便于比较,将空值填充为0处理(第7/9行代码中实现)。
  41.             return np.NaN
  42.         else:
  43.             if dj <= x['TARGET']:  #[‘TARGET’]为目标字段,用于比较
  44.                 return 0
  45.             else:
  46.                 if dj_x2 == 0:
  47.                     return dj - x['TARGET'] -1
  48.                 else:
  49.                     return dj - x['TARGET']

  50.     #新的x3存在空值的情况,需要事先填充
  51.     if output1 in condition: #这个情况,是根据用户需求,进行相应的输出。如用户有需求,则执行下面的代码
  52.         data['%s_x3'%i] = data.apply(tran_x3,axis=1)  #生成实时数据的x3
  53.         data['%s_x3'%i].fillna(-1,inplace =True) #因x3可能为0,空值需填充为-1,以便区分和格式转换
  54.         data['%s_x1x2'%i] = data['%s_x1x2'%i].astype(str)  #转字符格式,方便拼接
  55.         data['%s_x3'%i] = data['%s_x3'%i].astype(int).astype(str)
  56.         data['%s_x1x2x3'%i] = np.where(data['%s_x3'%i]!= '-1',data['%s_x1x2'%i]+data['%s_x3'%i],np.NaN) #生成单因子标识指数
  57.         data['%s_x1x2x3'%i] = data['%s_x1x2x3'%i].astype(float)  #求X1X2前,需记得将字符串转浮点型格式,否则无法求均值。
  58.     if output2 in condition:
  59.         f_data['%s_x3'%i] = f_data.apply(tran_x3,axis=1) #生成综合数据的x3
  60.         f_data['%s_x3'%i].fillna(-1,inplace=True)
  61.         f_data['%s_x1x2'%i] = f_data['%s_x1x2'%i].astype(str)  #转字符格式,方便拼接
  62.         f_data['%s_x3'%i] = f_data['%s_x3'%i].astype(int).astype(str)
  63.         f_data['%s_x1x2x3'%i] = np.where(f_data['%s_x3'%i]!= '-1',f_data['%s_x1x2'%i] + f_data['%s_x3'%i],np.NaN)
  64.         f_data['%s_x1x2x3'%i] = f_data['%s_x1x2x3'%i].astype(float)
  65. t06 = time.time()
  66. print(t06-t05)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-5-30 07:31:31 | 显示全部楼层
我觉得你再python里追寻速度问题,这本身就错了

如果速度真的达到了无法忍受的地步,你是否要考虑更换工具呢  如果你舍不得python的话
那你还是忍受它的速度吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-30 08:18:14 | 显示全部楼层
wp231957 发表于 2019-5-30 07:31
我觉得你再python里追寻速度问题,这本身就错了

如果速度真的达到了无法忍受的地步,你是否要考虑更换工 ...

python速度不快,我理解。
我的意思是,我的代码是否已经达到了python的速度极限了呢。。
因为之前不同的python代码,其运行速度也相差很多。。
我是希望在可能的情况下,尽量优化器速度。。
论坛上看到过jit的方法来提速。。可以成百倍地提高。。
我自己按照上面的试了下,却发现会报错(完全照抄例子,可以和帖子的一样,照常运行。但是按照帖子的方法,应用到我的代码上,就不行了)。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-30 10:56:10 From FishC Mobile | 显示全部楼层
如果做数据处理大部分在调c的库,这个速度不用关心,如果不用c库只做普通运算那就用pypy,也可以尝试cython,如果速度还忍受不了只能换语言了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-30 11:04:53 | 显示全部楼层
幽梦三影 发表于 2019-5-30 10:56
如果做数据处理大部分在调c的库,这个速度不用关心,如果不用c库只做普通运算那就用pypy,也可以尝试cython ...

不懂你的意思。
1. 我就是在进行数据处理运算。。这个调用c的库,是自动调用的?
2. 你所谓的普通运算是指的什么样的? 四则运算?
3. 如何尝试cpython?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-30 11:32:14 From FishC Mobile | 显示全部楼层
1,你既然用的c库那就不用关系速度了,本事就很快
2,普通运算说的是不用c库,直接用Python运算
3,不是cpython,是cython。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-5-30 11:56:56 | 显示全部楼层
幽梦三影 发表于 2019-5-30 11:32
1,你既然用的c库那就不用关系速度了,本事就很快
2,普通运算说的是不用c库,直接用Python运算
3,不是c ...

1. 我不知道我有没用你说的c库。。。我就是常规的调用pandas和numpy这些库。。
2. 如果我直接用的python,如何改用c库来运算呢?
3. cython,是另外一个库?也要pip install? 安装了之后如何调用?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-5-30 12:16:26 From FishC Mobile | 显示全部楼层
numpy是用c语言写的,你调用numpy就有了c速度
cython网上资料很多,有兴趣可以看看
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-1-16 03:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表