EXCEL 处理 ---pandas DataFrame 专题

  大家在处理excel相关场景时,总会有各种处理表格的需求,目前咱们设计器组件已经有了表格数据模块。《表格数据》模块使用的python库就是pandas,当然pandas功能很强大,能做到的不仅仅是控件上的那些。下面分享一些使用pandas的经验,希望对大家有所帮助。
DataFrame 类型类似于数据库表结构的数据结构,其含有行索引和列索引,可以将DataFrame 想成是由相同索引的Series组成的Dict类型。在其底层是通过二维以及一维的数据块实现。
例子:
df = pd.read_csv(filepath_or_buffer=path,encoding='utf-8',engine='python',usecols=[1,4],dtype={0:'str'})

常用参数

filepath_or_buffer 表格路径(注意\转译问题)
header : int or list of ints, default 'infer'
指定行数用来作为列名,数据开始行数。如果文件中没有列名,则默认为0,否则设置为None。如果明确设定header=0 就会替换掉原来存在列名。header参数可以是一个list例如:[0,1,3],这个list表示将文件中的这些行作为列标题(意味着每一列有多个标题),介于中间的行将被忽略掉(例如本例中的2;本例中的数据1,2,4行将被作为多级标题出现,第3行数据将被丢弃,dataframe的数据从第5行开始。)。
注意:如果skip_blank_lines=True 那么header参数忽略注释行和空行,所以header=0表示第一行数据而不是文件的第一行。
encoding : str, default None
指定字符集类型,通常指定为'utf-8'. 碰到如下报错可以尝试修改 'utf-8','gbk','gb2312'
engine : {'c', 'python'}, optional
使用的分析引擎。可以选择C或者是python。C引擎快但是Python引擎功能更加完备。
usecols : array-like, default None
返回一个数据子集,该列表中的值必须可以对应到文件中的位置(数字可以对应到指定的列)或者是字符传为文件中的列名。例如:usecols有效参数可能是 [0,1,2]或者是 ['foo', 'bar', 'baz']。使用这个参数可以加快加载速度并降低内存消耗。
dtype : Type name or dict of column -> type, default None
每列数据的数据类型。例如 {'a': np.float64, 'b': np.int32};{0: 'str', 1: 'int'}

EXCEL 处理 ---pandas DataFrame 专题
DataFrame 数据切片

df.iloc[3:7,:8]   截取3至7行,0至8列的数据表格
df[3:7]     截取3至7行
df.iloc[6,7]    获数据表格中获取第7行,第8列的数据
df = df[['开发部门','应用工作','是否重点','是否重要','是否更改','监管']]  按表头获取 只取这些列

DataFrame 数据筛选

#对一列进行数据筛选
df = df[df['中心项目编号']=='k20160838'] 
#对多列进行数据筛选   and or & |
df = df[(df['开发部门'].str.find('开发')!= -1) & (df['项目状态'].str.find('合并')== -1) ]
#Pandas 文本数据方法 contains() 是否包含查找的字符串
df = df[df['产品代码'].str.contains("wj")]
#match()  是否匹配正则
df = df[df['邮箱'].str.match("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$")]
#当值为多个时  使用isin方式更佳
df = df[df['中心项目编号'].isin(['k20160838','k20160841'])]

DataFrame 其他常用方法

df.shape   返回一个元组 (行数,列数)
df.empty    判断dataframe 是否为空  也可以使用df.shape[0] == 0 ; len(df) == 0
column_list = df.columns.tolist()     获取表头  list
data_list = df.values.tolist()      数据表格转list 二维数组
df['中心项目编号'].tolist()      数据表格指定列转list
df['修改时间'] = ''       在dataframe最后添加一个新的列,值均为空串

DEMO:读取工单处理结果日志文件 构造 DataFrame 并输出 excel

#result_flg 处理结果 
def write_log(work_code,job_type,result_flg):
    today_file = open(code_path+’\\’+today_flg,’a+’)
    if work_code is None or not work_code.strip():
        pass
    else:
        today_file.write(job_type + ’;’ + work_code + ’;’ + result_flg)
    today_file.close()
def write_log_to_excel():
    data_titles = ['处理类型','业务编号','处理结果']
    data_values = []
    result_file_name = 'car_result%s.xlsx' % yesterday_flg
    with open(code_path+'\\'+ yesterday_flg) as file:
        try:
            for line in file:
                line = line.strip()
                line = line.strip('\n')
                if not line:
                    continue
                else:
                    tmp_data = line.split(';')
                if len(tmp_data) != 3:
                    continue
                data_values.append(tuple(tmp_data))
        except Exception as e:
            pass
    df = pd.DataFrame.from_records(data_values,columns = data_titles)
    result_file_path = code_path + '\\' + result_file_name
    df.to_excel(result_file_path,index=False)

DataFrame groupby 使用方法

# 按col1分组并按col2求和
print df.groupby(by='col1').agg({'col2':sum}).reset_index()
# 按col1分组并按col2求最值
print df.groupby(by='col1').agg({'col2':['max', 'min']}).reset_index()
# 按col1 ,col3分组并按col2求和
print df.groupby(by=['col1', 'col3']).agg({'col2':sum}).reset_index()

DEMO: 按类型筛选分 sheet ,邮箱号相同的数据金额列求和保存

def init_csv_data(csv_path,out_path):
    print('数据源位置:'+csv_path)
    if os.path.exists(csv_path):
        pass
    else:
        return False
    df = pd.read_csv(csv_path,header=None,engine='python')
    group_df = df.groupby(df[0])
    my_heads=['类型','地址','姓名','金额','邮箱','卡号','日期']
    writer = pd.ExcelWriter(out_path)
    df.to_excel(writer,'sheet1',index=False,header=my_heads)
    for one_group in group_df: 
        one_type = one_group[0]
        tmp_df = df[df[0] == one_type]
        result_df = pd.DataFrame()
        group_tmp_df = tmp_df.groupby(df[4])
        for one_another_group in group_tmp_df:
            address = one_another_group[0]
            one_address_df = tmp_df[tmp_df[4] == address]
            sum_amount = one_address_df.iloc[:, 3].sum()
            sum_tmp_df = one_address_df[0:1]
            sum_tmp_df[3] = sum_amount
            result_df = result_df.append(sum_tmp_df)
        result_df.to_excel(writer, one_type, index=False, header=my_heads)
    writer.save()
    print('数据筛选处理成功,输出路径:'+out_path)
    return True