前一段时间遇到了一次数据处理的问题,原始数据是CSV数据(逗号分隔),近百万条,要根据不同的公式对每一条进行计算。在使用EXCEL进行计算时,只要一动就会重新计算,而且时常出现无响应的状态,有好几次强行关闭导致重头再来。
考虑到数据量大,使用EXCEL计算可能不适合,才导致不停地死机。最初打算使用数据库来计算,没有数据量的限制,在查询和更新的时候速度很快。但是每一行计算的时候,对于结果不是简单地赋值,而是分段乘以比例再累加计算(类似于电费阶梯计算),思来想去,不知道如何使用SQL语句实现,有可能需要很多个不同的语句。与其这么麻烦,不如写程序来实现,于是打算使用现在很流行的PYTHON语言来处理,一是简单易学,二是有丰富的模块,说不定就有解决该问题的方法。
经过了解,有一个模块PANDAS能够方便的处理CSV数据,而且非常灵活,打算试一试,最终成功解决了问题,现将过程记录以便以后再使用。
##导入numpy和pandas模块 import numpy as np import pandas as pd
##设置显示的列数,全部显示,方便查看内容 pd.set_option('display.max_columns',None)
##每一列的标题 title=('列1','列2','列3','列4')
##设置每一列的数据类型 ##不设置会自动识别,但是有可能出错 dataType={'列1':str,'列2':str, '列3':str,'列4':float}
##读取数据文件 ##names指定每一列的标题 ##encoding设置文件编码 ##index_col=False,不使用第一列数据当索引,这时系统会对每一行数据生成索引,编号从零开始,而且索引号不是行号,即使排序后也不发生变化 ##dtype设置每一列数据类型 data=pd.read_csv('data.csv',names=title,encoding='GBK',index_col=False,dtype=dataType)
##添加结果列,全部赋值为0 data['结果']=0
##编写对每一行计算函数,后面调用 def calc(row): result=0 value=row['value'] ##根据列1和列2的具体情况,分别设置阶梯分段计算语句 ##以下为其中一种情况 if value<200:result=0 elif value<1000:result=(value-200)*0.6 elif value<10000:result=(1000-200)*0.6\ +(value-1000)*0.7 ........ return result
##使用calc函数对表的每一行计算,并将结果赋值给结果列 ##calc为上面定义的回调函数 ##axis,1是对每一行计算;0是每一列 data['结果']=data.apply(calc,axis=1)
##对于计算的结果,按照列3聚合计算,方式为求和,当然除了求和,还有其他很多种类,比如次数、平均值等,下面对计算结果按照列3进行汇总 ##类似于SQL句的select 列3,sum(结果) ## from data ## groupby 列3 result=data.groupby('列3').agg({'结果':np.sum})
以上过程已经基本解决了问题,对每一行计算结果后汇总,或者又进行简单地计算再汇总。随后又进行了新的尝试,上面每一条数据根据列1和列2的不同,分别计算结果,假设对于每一个列3的数据,第一次、第二次、第三次的计算方式又不一样,因此又增加了一列’次数’,并针对此处又编写了公式(在calc函数里面增加判断条件)。这里记录一下如何计算每一个列3信息的次数。
##首先调取所有列3的数据,也就是取唯一值 ##类似于SQL句的select distinct 列3 ## from data ids=data['列3'].unique()
##增加记录次数的列,全部赋值为0 data['次数']=0
##针对每一个列3的数据,列出相关所有的记录,按照时间排序,根据每一条记录的索引号(排序之后不会发生变化),来更新次数信息,这里以一个列3的数据举例: ##取出列3信息为ids[0]的所有记录,并按照时间排序,假设数据中有'时间'列 ##排序有升序降序之分,通过ascending区分,此处按默认排序 ids0=data[data['列3']==ids[0]].sort_value('时间') ##此时已排序,取出所有ids[0]记录的索引,并按照1,2,3,4的顺序赋值给次数列 i=1 for iIndex in ids0.index: data.loc[iIndex,'次数']=i i=i+1 ##将结算结果保存成EXCEL ##参数为文件名,编码格式 data.to_excel("result.xlsx",encoding="GBK")
EXCEL虽然慢,但是并非没有解决的办法,因此重新用EXCEL解决了一遍,详见《一次较大规模数据处理的经历 EXCEL版》。
百万条的数据,excel处理应该不来的,