遇到复杂条件下海量的数据透视任务,excel难以驾驭。如对不同部门在不同年份吸收了什么学历的员工,pandas的筛选发挥了神奇的作用。
一、导包
pip install pandaspip install pyopenxlpip install tqdm
pandas依赖的xlrd可能不支持对xlsx的读取,解决方法有但比较麻烦,直接下载pyopenxl会方便很多。tqdm是进度条。
import pandas as pdfrom tqdm import *
二、读取数据
xlsx文件中可能存在各种类型的数据,pandas对这些数据进行读取时,一般直接读取过来时,数字在导出时会被转化为浮点数,不便处理,因此需要考虑dtype的问题。
pandas支持float、int、bool、datetime64[ns]、datetime64[ns, tz]、timedelta[ns]、category、object,object应该能满足大部分需求了。
file = r'E:\XXX\XXX.xlsx'# 默认读取第一张sheetdf = pd.read_excel(file)# 对第二张sheet按object格式读取df = pd.read_excel(file, 1, dtype=object)
也可以对不同列分别指定读取:
file = r'E:\XXX\XXX.xlsx'df = pd.read_excel(file, 1, dtype={'某列': object})# 配合import numpy as npdf = pd.read_excel(file, 1, dtype={'某列': object, '某列1': np.int})
三、设定行列
pt_index = list(df.drop_duplicates(subset='部门代码')['部门代码'])pt_name = list(df.drop_duplicates(subset='部门名称')['部门名称'])columns = ['部门代码', '部门代码', '985','211', '硕士以上', '2级以上']
我们读取的文件里面的部门代码和部门名称去重之后生成的列表,可以作为输出用的表格(df_op)头两列来使用。
df_op = pd.DataFrame(columns=columns)df_op['部门代码'] = pt_indexdf_op['部门名称'] = pt_namedf_op.set_index('部门代码', inplace=True) # 将部门代码作为索引
如此行列的框架就搭好了。
四、数据处理(多条件筛选)
excel多条件筛选的逻辑,pandas应该都能实现。
&表示且,|表示或,!=表示非,> <也可以使用,另有包含文本。
for year in ['', '', '']:for pt in pt_index:# 筛选不同部门不同年份入职的毕业于985职级在2以上的员工df_temp = df.loc[(df['部门代码'] == pt) & (df['入职年份'] == year)& (df['985'] == '1') & (df['职级'] > '2')]# 也可以用|来表示或者df_temp = df.loc[(df['部门代码'] == pt) & (df['入职年份'] == year)& (df['985'] == '1') | (df['职级'] > '2')]# 神奇的文本筛选也可以实现,如筛选王姓df_temp = df.loc[(df['部门代码'] == pt) & (df['入职年份'] == year)& (df['985'] == '1') & (df['姓名'].str.contains('王'))]# 不等于即!=当然可以用df_temp = df.loc[(df['部门代码'] == pt) & (df['入职年份'] == year)& (df['985'] != '1') & (df['职级'] > '2')]# 统计数量,后面随便按哪列不设条件筛选,再count一下即可df_op.loc[[pt], ['985']] = df.loc[(df['部门代码'] == pt) & (df['入职年份'] == year) & (df['985'] != '1')]['部门代码'].count()
多列间数据汇总
df_op['xx条件以上的人'] = df_op[['某条件人数', '某条件1人数', '某条件2人数', '某条件3人数',]].apply(lambda x: x.sum(), axis=1)
axis在pandas中,0表示列,1表示行。
五、数据输出
df_op.sort_index() # 排个序df_op.to_csv('%s年入职各部门员工学历情况.csv' % year, encoding='utf_8_sig') # 输出格式注意一下,避免中文乱码。
pandas输出后,可能有中文乱码的情况。
前言:在写入csv文件中,出现了乱码的问题。
解决:utf-8 改为utf-8-sig
区别如下:
1、”utf-8“ 是以字节为编码单元,它的字节顺序在所有系统中都是一样的,没有字节序问题,因此它不需要BOM,所以当用"utf-8"编码方式读取带有BOM的文件时,它会把BOM当做是文件内容来处理, 也就会发生类似上边的错误.
2、“uft-8-sig"中sig全拼为 signature 也就是"带有签名的utf-8”, 因此"utf-8-sig"读取带有BOM的"utf-8文件时"会把BOM单独处理,与文本内容隔离开,也是我们期望的结果.