鱼C论坛

 找回密码
 立即注册
查看: 1037|回复: 3

[已解决]代码优化求助

[复制链接]
发表于 2019-6-20 14:45:11 | 显示全部楼层 |阅读模式

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

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

x
手头一组数据,因存在缺失的情况,需进行填充处理。
数据大致情况为:
1. 为数十家企业的时间记录数据;
2. 每家企业的数据情况各不相同,需分组进行填充;
3. 因数据缺失情况各不相同,因此,暂考虑填充的原则是:
1)如数据缺失量超过该企业数据量的一半以上,则缺失处直接填充数值0;----缺失较多,说明很可能平时数据就是0。
2)如数据缺失量较少,则按照线性插值法填充数据;---数据缺失较少,说明平时应有数据,无法找出其规律,暂以线性插值,来近似替代。
数据结构如下:
3.png

我自己写了代码,但是对于4W+的数据,其运行速度很慢。。想不出,如何利用内置方法来快速处理。。
  1. data_new = pd.DataFrame(columns=data0_new.columns) #先创建个空列表,方便后期合并
  2. for i in data['COMPANY'].unique(): #分别针对每家企业进行填充缺失值
  3.     data_new1 = data[data['EQP_ID'] == i] #提取每家企业的数据
  4.     for i2 in data_new1.columns: #对每个字段进行遍历
  5.         if data_new1[i2].isnull().sum()> data_new1.shape[0]/2 : # 缺失值情况超过一半,则直接填充指定值。
  6.             data_new1[i2].fillna(0,inplace=True) #对其他值填充数值0
  7.         else:
  8.             data_new1[i2].interpolate(method='linear',limit_direction = 'both',inplace=True) #数据缺失未超过一半的,按线性插值法填充
  9.     data_new = pd.concat([data_new,data_new1],axis=0,sort=True) #拼接每家企业的数据表
复制代码


求高手帮忙~~
最佳答案
2019-6-20 17:16:47
  1. import pandas as pd


  2. # data.csv 是我随机生成的 48 行 5 列['COMPANY', 'X1', 'X2', 'X3', 'X4']的数据,并随机填充了空值
  3. data = pd.read_csv('data.csv')


  4. def f1(df):
  5.     # 这里的 df 其实就是 groupby 后形成的 DataFrame
  6.     # 调用 df 的 apply 方法,传入 f2,按列操作,得到填充后的 DataFrame 并返回
  7.     result = df.apply(f2, axis=0)
  8.     return result


  9. def f2(s):
  10.     # 这里的 s 是函数 f1 中 df 的每一列数据
  11.     # 判断该列数据缺失值是否超过一半,若超过则填充 0;否则线性填充
  12.     if s.isnull().sum() > len(s):
  13.         result = s.fillna(0)
  14.     else:
  15.         result = s.interpolate(method='linear', limit_direction='both')

  16.     return result

  17. # 将 data 按 COMPANY 分组后,调用 apply 方法,传入 f1,得到填充好的 48 行 4 列 的 DataFrame
  18. data_fill = data.groupby('COMPANY').apply(f1)
  19. # 用 data_fill 覆盖掉 data 的后四列
  20. data.iloc[:, -4:] = data_fill
  21. print(data)
复制代码


data.zip (1.41 KB, 下载次数: 1)

可能和你实际处理的过程有些区别,仅供参考
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-6-20 14:47:01 | 显示全部楼层
我自己后面又想用函数定义的方法,来简化代码,也希望可以提升速度。。结果却报错:insert() got an unexpected keyword argument 'axis'。
  1. def insert(x,i):
  2.     if x[i].isnull().sum() > x.shape[0]/2:
  3.             x[i] = x[i].fillna(0)
  4.     else:
  5.         x[i] = x[i].interploate(method='linear',limit_direction = 'both')
  6.     return x[i]
  7. for i in data_test.columns:
  8.     data_new[i] = data_new.groupby('EQP_ID').apply(insert,axis=1,args=(i,))
复制代码

我是需要对每列都适用该函数,设置axis=1,是很正常的啊。。为什么说没有该参数?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-20 17:16:47 | 显示全部楼层    本楼为最佳答案   
  1. import pandas as pd


  2. # data.csv 是我随机生成的 48 行 5 列['COMPANY', 'X1', 'X2', 'X3', 'X4']的数据,并随机填充了空值
  3. data = pd.read_csv('data.csv')


  4. def f1(df):
  5.     # 这里的 df 其实就是 groupby 后形成的 DataFrame
  6.     # 调用 df 的 apply 方法,传入 f2,按列操作,得到填充后的 DataFrame 并返回
  7.     result = df.apply(f2, axis=0)
  8.     return result


  9. def f2(s):
  10.     # 这里的 s 是函数 f1 中 df 的每一列数据
  11.     # 判断该列数据缺失值是否超过一半,若超过则填充 0;否则线性填充
  12.     if s.isnull().sum() > len(s):
  13.         result = s.fillna(0)
  14.     else:
  15.         result = s.interpolate(method='linear', limit_direction='both')

  16.     return result

  17. # 将 data 按 COMPANY 分组后,调用 apply 方法,传入 f1,得到填充好的 48 行 4 列 的 DataFrame
  18. data_fill = data.groupby('COMPANY').apply(f1)
  19. # 用 data_fill 覆盖掉 data 的后四列
  20. data.iloc[:, -4:] = data_fill
  21. print(data)
复制代码


data.zip (1.41 KB, 下载次数: 1)

可能和你实际处理的过程有些区别,仅供参考
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-20 17:24:17 | 显示全部楼层
在东边 发表于 2019-6-20 17:16
可能和你实际处理的过程有些区别,仅供参考

感谢~~
我后面请教了别人,也做出来了。。
基本和你差不多。。只是我只定义了一个函数,该函数传入2个参数。。也解决问题了。·~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-10-31 14:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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