导图社区 Python数据分析之Pandas
Pandas库的基本操作及主要数据对象的属性及内置方法,干货满满,有需要的朋友赶紧收藏吧!
编辑于2024-02-07 08:32:49Python数据分析之Pandas
Dataframe对象
aggregate()
简称agg(),统计学词汇,是指对一组数据进行某种形式的汇总和计算
append:df1.append(df2) 注意两个df对象的数据结构(列结构)
apply:
df2 = df.apply(lambda x: x.max() - x.min()) 新建一个DataFrame对象,计算各列的最大值-最小值
df2 = df.apply(lambda x: x.max() - x.min(), axis= 1) 新建一个DataFram对象,计算各行的最大值-最小值,
df_sum["日期"] = df_sum["费款所属期起"].apply(lambda x: next_month(str(x).replace("-", ""))) 可以实施较为复杂的公式计算,str(x).replace("-", "")首先剔除了指定列“费款所属期起”中的字符"-",进而运用自定义函数更新数据(含插入数据)
df['父节点'] = 's' + df['dd_id'].apply(lambda x:str(x)[1:]) 将“父节点数据列”数据替换为当前记录的‘dd_id’数据列按指定规则运算后的结果,即:字母s开头,加上dd_id列数据第2个开始至结尾的字符,组成的新字符【即将dd_id列数据首字母替换成s】
astype()
转换数据格式(由于数据规范性原因,不能转换的会报错)df['price'].astype('int')将数据列格式转化为int类型
df.astype({'Q1': 'int32','Q2':'int32'}).dtypes
at:df.at[5,"列名"] 返回索引号为5对应数据行的指定列名的数据值
attrs
axes
concat():
pd.concat(objects,axis=0,join='outer',ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False,copy=True) 参数 objects:DataFrame或者Series axis:0或者1,默认为0,纵向合并数据 join:inner(交集)、outer(联合),默认outer ignore_index:boolean,默认为False,如果为True,不使用索引,不指定为True时会将索引一并添加,可能出现索引值重复的情况 keys:序列,默认无,使用传递的键作为最外层构建层次索引,如果是多索引,应该使用元组,会强制取消索引,在原索引前增加一列(keys传入的list对象),类似pivot,只会在首行展示下“标识”,后续同一“标识”下的其他行数据为None levels:序列列表,默认无,用于构建MultiIndex的特定级别(唯一值),否则会将从键截断 names:list,结果层次索引中的级别名称,传入keys对象后,通过该参数指定“层次索引”的列名,便于后续引用 verify_integrity:boolean,默认False,如果True将会检验连接轴是否包含重复项 copy:boolean,默认True,如果为False将不会复制数据
columns()
df.columns()查看列名
df.columns.values[10]='XXX' 修改第11列的列名为XXX df.columns.value["ori_name'] = 'des_name' 通过列名锁定并更新数据列名称
df.columns=['x','y','z'] 通过一个与列数相等的list对象,更新全部列的名称
copy():
通过copy()方法可以建立一个与原dataframe“数据隔离”的副本,df2=df1,新建的df2实际引用了df1的内存空间,会随着df1的变动而自然更新,如果不希望更新可以df2=df1.copy(),这样在另外一个内存空间建立了一个数据副本
cumsum()
计算数据的累计和
cut
df['分类标记列'] = pd.cut( x = df['销售额'],bins = [0,100,1000,10000,100000], right = false, labels = ['较差','一般','合格','优秀']) # 在分类标记列中根据销售额设置5个节点,按照right为false的划分标准,分成了4个区间档次,按照“左闭合、右开放”的原则 #(right = True的,对应左开放,右闭合原则)将四个档次分别用制定的标签赋值描述
del:del df['待删除列名']
describe():对数据列给出摘要或描述性统计信息
不带任何参数下运行结果
遇到文本型数据:返回4个统计结果“数据条目数,唯一值数量,top,出现次数”
exclude
df.describe(exclude='number') 统计所有非数字列(如字符串)的数据,number和all必须要用括号前后围起来,其他数据类型不用加符号
include参数
df.describe(include=int)) 统计所有int型的数据 df.describe(include=[object, bool]) 统计指定类型的数据列
at
df.describe().at['std', 列名],可以读取统计维度下,指定列的数值
loc
df.describe().loc['std'] 对于数值型数据的统计结果,可以通过loc[索引名称]读取series对象,索引名称有:count、mean、std、min、25%、50%、75%、max
diff():对比对象内部的相互变化
# 通过两个list对象用合并成一个集合对象,以二维数据形式创建DataFrame对象。典型用途是日期时间为索引的数据集,调用该方法可快速计算环比变动值 df = pd.DataFrame({'A': [1, 2, 3, 4, 5], 'B': [5, 4, 3, 2, 1]}) diff_df = df.diff(periods=1,axis=0) 效果:按照行(axis=0)方向,向后相邻1单元(periods=1)做“减发”变动计算,即本行数据减去上一行同一列数据的结果,存入新的DataFrame,由于第一行(index=0)没有“上一行”,因此新生成的DataFrame对象首行为空(NaN)
drop
依据index列的不同取值条件,删除数据行 df.drop(index=range(0,7), inplace=True)
删除行
通过loc+条件的方式,锁定series对象,调用锁定对象的index属性,依据index属性删除数据行 df.drop(index=df.loc[df['指定列']=='XXX'].index, inplace=True)
通过指定数据列名、列序号的方式删除数据 df.drop(df.columns==['ID','销量']) df.drop(df.columns==[[4,5]], axis=1) # 指定列名并明确axis参数值为1,表示按列删除数据,删除列 df.drop(columns=['医保单位附加', '医保单位'], axis=1, inplace=True)
删除列
dropna
df.dropna(axis=0, how="any", thresh=None, subset=None, inplace=True) 默认删除一行中只要有一个字段为空就会被删除 axis=0或"index"表示按行删除,1或"columns"表示按列删除 how:any表示只要有1个NaN,就删除整行(或列),all表示全部都是NaN才删除行(或列) thresh:int型数据,非空数据个数小于指定值时,删除行(或列) subset参数:制定删除数据方向中指定的行或列有空值时,予以删除。 inplace参数默认为false表示不替换源数据,如果设置inplace参数为True就会将数据操作更新到源数据中
df.dropna(axis=0, subset=['姓名'], inplace=True) 表示只有当姓名字段为空的数据行,才会被删除
dtypes:了解数据的性质和每列数据类型,便于数据整理
duplicated():df.duplicated().any()查看是否存在重复数据
empty
expanding
数据累计计算
explode()
将一行数据拆分成多行 result = df.explode('Names')
ffill():根据前一行或列的数值,向空白值位置填充数据
df_cftc["发薪机构"].ffill(axis=0, inplace=True)
fillna()
drop_duplicates
删除重复数据
df.drop_duplicates(inplace=True) 默认删除两行完全一致的重复记录,删除后会保留其中一个 inplace参数默认为false表示不替换源数据,如果设置inplace参数为True就会将数据操作更新到源数据中
df.drop_duplicates( subset('姓名') , keep = 'last') 删除姓名列重复的记录,默认删除后只保留第一次出现重复姓名的行,之后重复行均被删除,不论重复行其他字段情况。 通过给keep赋值为last也可以选择保留重复记录中的最后一行,keep参数默认值为first,所以默认保留重复记录的第一行
df_dup = df.loc[df.duplicated('姓名') == False , :] 快速定位非重复数据
fillna(value=None,method=None,axis=None,inplace=False,limit=None,downcast=None,**kwargs) value:用于填充空值的新数据 method:默认None,backfill或bfill表示用空白值后面的数据(是后面一行还是后面一列,看axis参数)填充,pad或ffill表示用空白值前面的数据(是前面一行还是前面一列,看axis参数) axis:0表示按行维度配合method选定方式填充空白值,1表示按列维度 inplace:原地替换 limit:int型参数,未指定method方式下,控制填充数量;指定method,控制每段连续空白值的填充数量
用指定值填充全部空白数据 df.fillna(value=0, inplace=True)
filter():针对数据列名称和索引字段开展应用数据筛选
参数中regex通过正则表达式约束筛选条件,like视作包含特定字符的通配符约束对象,axis确定是在列还是行对象中应用以上约束 df.filter[items=['工号', '姓名']) 相当于筛选了工号、姓名两列数据 df.filter(regex='收入', axis=1) 按列筛选对象,列名中包含'收入'两个字的数据列被选中 df.filter(regex='收入$', axis=1) 以'收入'两字结尾的数据列名称,被筛选中 df.filter(like='2', axis=0) 索引含有'2'的行被筛选中 筛选‘索引中以字符2开头'且'列名有字符Q'的数据对象(单列,可能多行) df.filter(regex='^2', axis=0).filter(like='Q', axis=1)
flags
groupby
db.groupby('客户分类').count() 按客户分类分组后计算数量,count的位置可以用其他统计函数代替,如sum、mean等
db.groupby('客户分类').aggregate({'销量':'sum','ID':'count'}) 按照客户分类后,按销量求和、按ID计数
df2 = df1.groupby(['发薪机构','月份']).aggregate({'在岗员工(人)':'sum','离岗员工(人)':'sum','工资总额':'sum'}) df2.reset_index("工号") 单一字段分组可能还有用,2个及以上字段分组后索引列必然无效了,需要重新设置索引
df_sum_4.loc[df_sum_4['养老保险个人额度'] != 0, :].groupby(by='月份')['工号'].count() 分组计算后的对象,数据类型变为Series,分类字段进入index,单一计数结果作为数据存储
head():df.head(5) 视作调取行索引0-4的前5行数据
iat:与loc和iloc的关系类似,iat与at是一组同样的读取对象数值的方法,df.iat[0,5]通过数值的方式,返回索引列数值为0的第5列对象数值
iloc
df.iloc[行索引, 列索引],依靠数字的位置索引调取元素,从0起算含首不含尾。
df.iloc[0:13,:] 表示第1行到第12行,冒号指代所有列
df.iloc[:,[0,4]] 表示所有行,第1列和第5列
对于每列设置规范表头的数据表,可以用iloc快速锁定对象 print(df[df.iloc[:,1]=='2022年10月']) 列索引为1数据列中取值为'2022年10月'的数据行 print(df[df.iloc[:, 1]=='2022年10月'].iloc[:, 1:5]) 可以通过iloc不断缩小表格范围,聚焦目标数据
index
info():用于快速查看表格的列数、列标签、列数据类型、内存使用情况、范围索引以及每列单元格数(非空),为后续数据处理做准备
insert()
在指定位置(第0列)插入一列(列名为日期,数据全部用date填充),再用append、extend等方法增加数据 df.insert(loc=0, column='日期', value=date)
isnull():db.isnull().sum() 返回表格各列中空值数量
lambda
df.工号[lambda s:max(s.index)] dataframe对象中索引列数值最大的那行数据中,工号字段的数值
# 将工号列强制转换为6位字符并对长度不足的字符自动在前方补0 df_pending['工号'] = df_pending['工号'].apply(lambda x: "0"*(6-len(x)) + x)
# 更新 付款月份 数据列 df_sum["实际付款月份\n例:202301"] = df_sum["费款所属期起"].apply(lambda x: next_month(str(x).replace("-", "")))
# 通过lambda简化数据多条件筛选条件 fruit2 = fruit.loc[fruit.价格.apply(lambda a:10<=a<=20)].loc[fruit.数量.apply(lambda s:70<=s<=100)]
loc
df.loc[:,'工号'] 依靠列表对象枚举的方式调取数据,第一个参数用冒号代替,相当筛选指定列 df.工号 能达到同样的效果,返回一个Series对象,dataframe.列名的方式可以选取单一列,多用于多条件筛选中简化代码 df.loc[:,:'工号'] 选取所有行,只选择工号列及之前的数据列,“冒号”实际用于表示一个范围,如两侧全部缺失则表示“全选”行或者列
dataframe = df.loc[df["级别"]=='一级',:] 将表内“级别”列的数据中等于“一级”的行全部选中
df.loc[:,['销售渠道','平均销售单价'] 将表内标售渠道和平均销售单价两列选中
df.loc[df["销售渠道"].isin(["淘宝","天猫"]),['销售渠道','销售数量','销售单价','销售额'] 将表内“销售渠道”是“淘宝、天猫”数据,对应的'销售渠道','销售数量','销售单价','销售额'予以选中,isin为判断时候在参数内的逻辑语句
df[~df["销售渠道"].isin(["京东","拼多多"])],相当选取“销售渠道不是京东、拼多多”的数据行
df.loc[len(df)]= [……] 在df对象的最后一行追加数据
将指定列中的空白数据填充为单一值
df_detail_lastmonth.loc[df_detail_lastmonth['岗位名称'].isnull(), '岗位名称'] = '无'
map():将对象中所有元素按照指定的方法处理一遍
利用str.strip可以清除字符串内的特殊字符(如前后方空格,字符串内转义字符),清除数据列中的无效空格 df['city']=df['city'].map(str.strip)
merge
pd.merge(left = df1 ,right = df2 ,on=['工号','姓名'], left_index = true ,right_index = true, how = 'inner') on:表示表格链接的数据列,也可以是left_on = '姓名',right_on = '姓名',若链接数据列是索引列(不是公共列),需要用left_index、right_index描述 how:表示连接方式inner表示两个表里同时存在的数据行作为匹配对象,参数除了inner以外,还有outer、left、right,其中:left和right分别表示以两表之一为主表匹配数据,不在主表内的数据忽略不计,主表内有但次表无的,返回NaN数据表示空白,outer表示只要两张表里有的就全部对接合并 left_on和right_on:确定连接两表的关键字段,相比“on=list,left_index,right_index”更加直观,因为链接字段很有可能不是索引字段 suffixes:重复列名的重命名,合并时预计在输出结果中按“原表列名”会重现重复列名,增加suffixes('_left','_right')参数后,会自动调整列名以区别显示 indicator:标识列,在结果数据集中的最后一列增加一列“标识”,indicator=True(列名为_merge)或者indicator='指定列名',填入“both”(标识该数据在两张表里都存在)、”left_only"(仅存在于左表)、“right_only"(仅存在于右表)
df_result = pd.merge(df_node_dd, df_node_sd, how='inner', left_on='sd_id', right_on='sd_id') 将两个表格合并,合并双方共有数据,共有的判定通过left_on和right_on的对应情况
nlargest
df.nlargest(6,'年龄') 年龄列最大的6行,这6行数据自上而下年龄逐步递减,索引仍为原df对象中的索引号,对非数值字段应用时会报错
df['A'].nlargest(2) 数据表中A列中最大的2个值,返回Series对象
nsmallest
df.smallest(6,'年龄') 年龄列最小的6行,这6行数据自上而下年龄逐步递增,索引仍为原df对象中的索引号,对非数值字段应用时会报错
df.loc[:, ['工号', '员工姓名', '应发额']].nsmallest(10, "应发额") 可以用这种方式筛选指定列最小n行数据
df['A'].nsmallest(2) 数据表中A列最小的2个值,返回Series对象
pct_change():类似diff,比较表内数据的比例变动
df = pd.DataFrame({'A': [10, 15, 20, 25], 'B': [5, 7, 10, 15]}, index=pd.date_range('2023-01-01', periods=4)) pct_change_df = df.pct_change(periods=1, fill_method='bfill', axis=0) 解读:按行(axis=0),每行向上做“减法”。 periods:指定计算百分比变化的周期数,默认为1。 fill_method:指定如何填充缺失值,可选参数包括backfill、bfill、pad、ffill、nearest等。默认为pad。 limit:指定连续缺失值的最大填充数量。默认为None。 freq:指定时间频率,用于计算时间序列数据的百分比变化。默认为None。 axis:指定计算的轴,0表示按列计算,1表示按行计算。默认为0。
pivot_table():数据透视表
pd.pivot_table(df,values=['ID','销量'], index='客户分类', columns='区域', aggfunc={'ID':'count','销量':'sum'}, fill_value=0,margins=True,dropna=None,margins_name='总计') values:需要聚合运算的列名集合 index:聚合运算的分类字段 columns:列方向的分类(列索引)集合 aggfunc:通过字典指定values对象中各项目的聚合运算方法(sum、mean、max等) fill_value:指定用于替换“透视表”中聚合运算后为空的数据(如:补0) margin:默认是False,用于控制是否添加行和列的小计数 dropna:是否删除所有条目都是NA的列,默认是True margin_name:与margin搭配使用,当margin为True时,本字段用于明确合计数的列名,如:总计
df_sum_2_pivot = pd.pivot_table(df_sum_2, index=['月份', '单位'], values=['养老保险缴费基数', '养老个人额度', '医疗个人额度', '失业个人额度'], aggfunc={'养老保险缴费基数': 'sum', '养老个人额度': 'sum', '医疗个人额度': 'sum', '失业个人额度': 'sum'}) df_sum_2_pivot.reset_index(drop=False, inplace=True) 通过给index传入list对象,透视表生成多级汇总数据,此时的索引列已经是两列的组合了,通过reset_index函数,不删除原索引的方式,可以达到拆分索引列效果
df_sum_pivot = pd.pivot_table(df_sum, index=['实际付款月份\n例:202301', '主体名称'], values=['缴费人数', '缴费基数(元)', '应缴费额(元)'], columns='征收品目', aggfunc={'缴费人数': 'mean', '缴费基数(元)': 'sum', '应缴费额(元)': 'sum'}, margins=False) index:相当Excel的行索引,当需要的索引字段是一个list对象时,在这里标识出。当索引维度为两个及以上时,透视表的行做引会被自动覆盖,有必要在实施完毕后重置索引(df.reset_index(Drop=false, inplace='True') values:相当数据透视表中待统计汇总的字段
plot()
import matplotlib.pyplot as plt # 通过DataFrame对象生成图表 fruit.plot.bar(x="水果名", y="数量", color="orange", title="水果数量显示图") plt.tight_layout() plt.show()
import matplotlib.pyplot as plt import pandas as pd
pop():
df.pop(3)删除索引为3的行数据
# 调整顺序,将指定列通过pop方法从原表格中剔除存入一个Series对象,再将该对象插入到表格中指定列位置,最终达成变更列顺序的需求 series_dw = df_sum_2_pivot.pop("主体名称") df_sum_2_pivot.insert(loc=1, column='主体名称', value=series_dw)
quality()
DataFrame.quantile(q=0.5, axis=0, numeric_only=True, interpolation='linear') 参数: q:分位值,在0至1之间取值,表示在一组从小到大排列的数据集合中“1+(数据条目数-1)×q(分位值)” axis:在{0,1,'index', 'columns'}之一取值,其中0和index相当,表示按行取数 interpolation:表示“取值方法”,可以在{'linear','lower','higher','midpoint','nearest'}之一,默认是linear 取值规则:linear:i+(j-1)×fraction,fraction采用计算分位值【“1+(数据条目数-1)×q(分位值)”】的小数部分 lower:i,较小的一个 higher:j,较大的一个 nearest:i和j中更接近的一个数值,“更接近”的定义不清楚 midpoint:(i+j)/2,相邻位置数据均值
query():调用SQL查询进行数据筛选
df.query('工号==\'550012\'') 查询表内工号为550012的数据,由于sql查询语句本身需要单引号,传入查询条件时需要转义字符参与,同时“等于”需要用Python的双等号
sample():db.sample(frac=0.25) 从数据集中抽取一个小的样本,如25%
rank()
df['销量'].rank(method='first') 排名,与排序有差异 参数: method参数有first(排名值相等的,原始位置靠前的排名在前)、min(排名值小的,位置靠前,相当升序排名)、max(与min相反)、average(当排名值有重复的,按排名值÷个数,如同一数字占据了2、3两个位置,则两个数字的排名均为2.5)、dense(排名值相等的,并列排名,后续的排名顺延,不会因为有两个2造成没人第3) axis:设置沿着哪个轴计算排名(0或者1) numeric_only:是否仅仅计算数字型的columns,布尔值 na_option:NaN值是否参与排序及如何排序(‘keep’,‘top',’bottom') ascending:设定升序排还是降序排 pct:是否以排名的百分比显示排名(所有排名与最大排名的百分比)
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 4, 3, 2], 'C': ['a', 'b', 'c', 'd'], 'D': [np.nan, 2, 3, 4]}) ranked_df = df.rank(axis=0, method='min', ascending=False, numeric_only=True, na_option='bottom', pct=False) 参数解读: method:指定排名的方式,可选参数包括average、min、max、first、dense。默认值为average。 ascending:指定排名的顺序,True表示升序排名,False表示降序排名。默认值为True。 axis:指定排名的轴,0表示按列排名,1表示按行排名。默认值为0。 numeric_only:指定是否只对数值类型的数据进行排名。默认值为True。 na_option:指定如何对NaN值进行排名,可选参数包括keep、top、bottom。默认值为keep。 pct:是否以百分位形式显示返回的排名。默认为False。 ranked_df内容:只处理数字型数据(numeric_only=True),比较同一列的各行数据(axis=0),本行数据的排序顺序为降序(method='min',最大值排1、最小值排最后),无论何种排序方式空值(NaN)都排在最后(na_option='bottom') A B D 0 4.0 1.0 4.0 1 3.0 2.0 3.0 2 2.0 3.0 2.0 3 1.0 4.0 1.0
rename()
修改索引的方式 db.rename(index={'0':'X','1':'Y'}) 如果不指明index参数,输入一个字典对象并附加axis='index'有同样效果
修改数据的列名 db.rename(index=None,columns={'原列1':'原列1新列名','原列2':'原列2新列名'}) 对列索引进行重命名 # 简化列名,即刻更新 df_ori.rename(columns={'在岗员工(人)': '在岗人数', '离岗员工(人)': '离岗人数'}, inplace=True)
用df的第5行作为列名 df.rename(columns=df.loc[5,:], inplace=True)
replace():
df['年龄'].replace(30,31) 将年龄字段中值为30的数值,替换成31
resample()
重采样方法,多用于时间序列的处理
reset_index()
# reset_index('列名') :指定列作为索引列 df3 = df2.groupby('工号')['合计'].sum() 这个写法的分组结果是“工号转入索引列、数据列仅有合计列数据” df3 = df3.reset_index('工号') 不增加这个方法,写入excel文件时会将工号列视作系统序号而删掉 df3.to_excel(writer, index=False, sheet_name='汇总', header=['工号','2022工资总额'])
df.reset_index() 将全部index转化为column
df.reset_index(level=0) 将第0行索引转化为column列名
db.reset_index(drop=True) 删除原有索引
db.reset_index("列名") 将制定列作为索引列
#对于groupby、pivo等方法生成的dataframe,因为采用多维索引,因此输出表单的索引不能继续使用,需要重置,但有保留的价值(转化成2列) df_sum_pivot.reset_index(drop=False, inplace=True)
select_dtypes()
通过数据类型筛选数据列(int型数据列) df.select_dtypes(include='int')
shape
以“(行数,列数)”格式返回datafram对象的行数、列数,通过“行×列”快速评估数据数量(规模),shape函数本身不是pandas库的方法,是numpy库的函数
shape[0]存储了dataframe对象的行数,shape[1]存储了dataframe对象的列数,多用于for循环中控制遍历上限
set_index():df.set_index('工号') 用指定列作为行索引
shift()
result = df['A'].shift(-1),位移数据
size
sort_index
df.sort_index() 按索引升序(默认)排序 df.sort_index(ascending=False, inplace=True) 按降序排序并替换现有索引 df['工号'].sort_index(inplace=True) 这个只会将指定列(工号)的数据进行升序排列,不会对其他列产生联动效应,相当于对一列Series对象排序 df.sort_index(inplace=True) 通过对索引列的排序,才能正确的对整表数据开展排序 df.sort_index(na_position='first') 空白字段排在前方,当first用last代替时,空白数据将排在末位 df.sort_index(axis=1) 会对列名开展排序
sort_values
df.sort_values(by=['工号'], ascending=False) 按工号降序排序 na_position参数:first或者last,制定缺失值的排序位置
df.sort_values(by=['部门','工号'], ascending=[False,True],inplace=True) 多列排序,按照部门降序、工号升序排列
split()
将一列拆分成多列数据 df['Names'].str.split('_',expand = True)
style
sum:df.sum(axis=1) 每列/行的求和结果,axis默认为0表示对列求和,指定1表示对行求和
T:转置,原索引(按行)转换后将作为“第一行”,需要删除,原横向的列名转化为纵向的索引号,df.T.to_excel('test.xlsx', index=False)会删除转置后的第一列
tail():df.tail(n) 查看对象最后n行
transform():df.groupby(col1).col2.transform("sum") 通常与groupby连用,避免索引更改
to_excel
df.to_excel(r'文件名', index=False, header=None, sheet_name='明细') 采取覆盖写入的方式生成文件
writer = pd.ExcelWriter('工资总额明细报表-筛选.xlsx', mode='a') 指定文件必须已经存在 df.to_excel(writer, index=False, header=None, sheet_name='明细')
to_dict
df.to_dict(orient='',into=),orient的参数决定了处理后的对象类型 orient='dict':可以通过df.to_dict(orient='dict')['月份'][4] 的形式访问二维表df对象中“月份”列的第5个元素 orient='list':可以通过df.to_dict(orient='list')['月份'][4]的形式访问二维表df对象中“月份”列,索引为4的元素 orient='series':可以通过df.to_dict(orient='series')['员工姓名'].iloc[4]的形式访问数据
unique():返回指定列的唯一值存入array对象,为便于调用可以结合tolist()方法。df['city'].unique().tolist()将数据列唯一值存入list对象
value_counts():df['ID'].value_counts() 统计指定列出现非空数据的次数
values
where
df.where(df['应发额']>30000).dropna() 将参数中的条件作为筛选条件,逐一匹配dataframe中的每行数据,符合条件的保留,不符合的用NaN空值代替,fillna清空空白行整理格式
统计方法
count:df.count() 统计每列非空数据个数,df.count(axis=1) 统计每行非空数据个数
max:求最大值
mean:求平均值
min:求最小值
median:求中间值(中位数)
mode:求出现次数最多的值
var:求方差
std:求标准差
quantile(0.25):求25分位数,可以用0.5、0.75等分位数
# 发薪机构与岗位类型与当前统计表“指定行”相关字段取值一致的,计算“大于80%数据值的,前20%的分位值” df_result_sum.iloc[row, 3] = salary_detail.loc[(salary_detail['发薪机构'] == df_result_sum.iloc[row, 0]) & (salary_detail['岗位类型'] == df_result_sum.iloc[row, 1]), '年初至本月累计应发'].quantile(0.8, interpolation='midpoint')
corr():求整个DataFram表中的相关性
部分实践方法
数据列文本替换:df2["姓名"].str.replace(' ',''),删除姓名列中的空格
新增数据列(由现有数据列计算生成)
# 依据“在岗人数、离岗人数”两列数据生成“在册人数”数据列,数据计算发放为sum,计算方向axis=1表示按列计算 df_ori['在册人数'] = df_ori[['在岗人数', '离岗人数']].sum(axis=1)
通过公式添加列
展示计算后的数据: print('平均销售单价',df2.['销售单价'].mean()),打印所有商品的平均单价,直接调用mean方法,类似的方法还有std标准差、median中位数、max最大值、min最小值 df2.loc[ (df2['销售量']>df2['销售量'].mean() ) & (df2['销售单价']>df2['销售单价'].mean() ) ,:] 选中了表格内销售量大于销量平均值 并且 销售单价大于平均单价的所有行
数据分列存储: pd.DataFrame((x.split('-') for x in df_inner['category']),index=df_inner.index,columns=['category','size'] 将一列有明显录入规则的数据,通过指定分隔符调用split方法拆分成两列数据并存入新的数据表
拆分合并单元格至每个分解单元格 df['单位'].fillna(axis=0, inplace=True) 已读取数据的datafram对象,先填充,本方法按上而下填充空值,形成一个中间文件 将中间文件数据写入原文件 for row in worksheet.iter_rows(): row_list[] for cell in row: row_list.append(cell.value) 通过逐一添加元素的方式,形成一个series对象 worksheet.apppend(row_list) 将新添加完成的series对象合并进入dataframe对象
df[df.工号.eq('550012')] 返回一个Series对象,里面以True/False存储了每个行数据与指定值的逻辑运算结果
比对两个从Excel读取出来的DataFrame对象的字段是否有差异,由于待比对数据为“数值型数据”因此在判断条件中除了判定“存在”还判断数据类型dtype if (df1.dtypes.index[num] in df2.dtypes.index.values) and (not df1.iloc[:, num].dtype is np.dtype(dtype='object')): check_list.append(df1.dtypes.index[num])
Series对象
可以理解为“附带索引的列表” S1 = pd.Series(['a','b','c']) S1 = pd.Series(['a','b','c'],index=(1,3,4)) 指定行索引编号 S1 = pd.Series({1:'a',2:'b',3:'c'})
value_count():可以统计各元素出现的次数
index():
isin()
# 可以通过比较两个Series对象来识别一个Series存在或不存在另外一个Series对象的数据,isin 的结果是一组布尔型数值的集合 ser1 = pd.Series([1, 2, 3, 4, 5]) ser2 = pd.Series([4, 5, 6, 7, 8]) # 返回ser1【不】包含ser2的布尔型series ser3=~ser1.isin(ser2) # 利用布尔型集合作为索引,获取ser1不包含ser2的元素 print(ser1[ser3])
# 比较两个Series中
将Series对象转化为DataFrame对象,当Series对象index列有名称(比如从dataFrame.groupby()运算而来的),不能指定列名,只能忽略columns参数,用其已有默认名称 df = pd.DataFrame(s, columns=['Number'])
基础的“读”、“改”、“存”
数据读取
pd.read_excel(r"……\XXX.xlsx",sheet_name='XXX',head=3) head参数指明了列名所在位置,head上的名称数据自动删除,head行的数据作为数据列名 sheet_name参数可以用工作表名(字符串),也可以用阿拉伯数字 index_col参数用于指定行索引
数据写入:
# 在已有数据文件中“增量写入数据: wirter = pd.ExcelWriter(r"……\XXX.xlsx", mode='a', ifsheet_exists='overlay') dataframe df.to_excel(writer, index=False, sheet_name='XXX', startrow=writer.sheet['XXX'].max_row) writer.close() #已经升级在关闭时自动保存
mode='w'方法,支持在文件不存在的情况下,新建
数据修改
将两列数据求和,计算方式可以指定(sum等)、计算方向也可以指定(axis=1表示按列求和) df['在册人数'] = df[['在岗人数','离岗人数']].sum(axis=1)