pandas手册(1)

您所在的位置:网站首页 英文早教动画片大全 pandas手册(1)

pandas手册(1)

#pandas手册(1)| 来源: 网络整理| 查看: 265

pandas手册(1版)

说明 :pandas可以理解为一个超级版本的Excel,最重要的区别在于处理的数据量(这里的数据量指的是记录数和数据维度), 超过10万的数据量,Excel就很吃力了,至于说代码可以解决重复的操作,但是Excel、power bi等都可以通过① 超级表 + 透透视表② 数据库 + power query + 透视表都可以实现自动化(只做一次,随着数据的增加,直接刷新就可以了);对于python 用于数据分析、数据挖掘、机器学习等等,绝逃不过python第三方库中的三剑客(numpy pandas matplotlib)

anaconda下载链接 : https://www.anaconda.com/ anaconda

安装、配置环境、修改jupyter文件储存的默认路径 :

https://zhuanlan.zhihu.com/p/511233749

https://blog.csdn.net/wzk4869/article/details/122618838

jupyter书写代码快捷键 : https://www.cnblogs.com/peilin1031/p/12326701.html

import numpy as np import pandas as pd %%HTML table.dataframe td, table.dataframe th { border: 1px black solid !important; color: black !important; }1 数据的加载与存储1.1 文本文件的加载与存储python用pandas加载和存储文件方法中的参数甚多,下面提到的参数可以决绝99%的问题` ① 加载文本文件 pd.read_csv("./test.txt"(相对路径),sep=' '(分隔符),encoding='编码格式') 编码格式如gbk,utf-8等 如果分隔符不止一种,使用正则表达式sep='\s+' (如果路径中含有中文可用: f=open("路径","rb") df= pd.read_csv(f,sep=' ',encoding='编码格式') 即可 ② 存储文本文件 df.to_csv('文件要保存到的路径')#默认 index=True 将行索引也保存1.2 excel文件的加载与存储① 加载Excel文件 pd.read_excel("./python.xlsx",sheet_name=0或者"str") # header=0:默认为0,使用第一行作为列标题,若本身无标题,则需要自定义列名 names=["a","b","c"] # sheet_name = none 默认读取全部sheet # sep : default ',' 以什么样的分割方式来读取文件,如果分隔符不止一种,使用正则表达式sep='\s+' # index_col=0 读的时候将第一列作为行索引,默认为none # encoding='编码格式'要统一编码, 通常都是 utf-8,如果是ASCII报错 # nrows =10000 从开头处读取10000行 ② 存储Excel文件 df.to_excel('文件要保存到的路径')#默认 index=False 不保存df的行索引1.3 数据库文件的加载与存储以mysql为例 方式① import pymysql con=pymysql.Connection(host="localhost",port=3306, user="root",password="12345", database="a1",charset="utf8") #host="localhost" 数据库服务器所在主机 #端口号:port=3306 #user="root"用户名 #password="*****"密码 #database="a1" 数据库 #charset="utf8" 编码(字符集) pd.read_sql("select * from score",con) 方式② from sqlalchemy import create_engine engine=create_engine( 'mysql+pymysql://root:12345@localhost:3306/a1?charset=utf8') df = pd.read_sql_query(sql, engine)#通过引擎读取数据 df8.to_sql('mydf', engine, index= False)#通过引擎保存文件1.4 千万级的数据量如何加载# 这一类读取文件的函数有两个参数:chunksize、iterator #read_csv 和 read_table 有一个 chunksize 参数,用以指定一个块大小(每次读取多少行), #返回一个可迭代的 TextFileReader 对象。 df = pd.read_csv('./abs.csv',iterator=True,encoding="gbk") f=df.get_chunk(3) f #通过get_chunk(size),返回一个size行的块 #通过chunksize,分块读取 df = pd.read_csv('./abs.csv',chunksize=10000,encoding="gbk")# 将此文件每10000行分为一块, list1=[] for i in df:#遍历每一块 list1.append(i)# 将n个块数据保存在列表中 df_csv = pd.concat(list1)#合并所有的块 df_csv1.5 合并一个excel工作簿中的多个sheet# 先合并 xl = pd.read_excel("./1.xlsx",sheet_name=None) # 获取所有sheet名字 # 如果read_excel参数不是None,则df.keys()为表头 sheet_names =list(xl.keys()) list2 = [] for sheet_name in sheet_names: list2.append(xl[sheet_name]) df_excel = pd.concat(list2,ignore_index=True) df_excel # 写入新的Excel文件 df_excel.to_excel("./总表.xlsx",index=False)1.6 合并指定目录下所有的 excel (csv) 文件#python 合并指定目录下所有的 excel (csv) 文件 import glob files = glob.glob("data/cs/.xls") #files = glob.glob("data/cs/.csv") dflist = [] for i in files: dflist.append(pd.read_excel(i, usecols=['ID', '时间', '名称']))#可以指定列 df = pd.concat(dflist) df ```2 清洗数据

注意 : 以下都是模仿在拿到数据后一般情况下的操作

# 例如获取到了如下数据 data = {'性别':['男','女','女','男','男'], '姓名':['小明','小红','小芳','大黑','张三'], '身高':[178,173,165,188,156], '年龄':[20,20,25,24,29]} df = pd.DataFrame(data) df2.1 查看# 获取到数据后先要查看一些信息 # ① 查看 df.head() # 前5行 df.tail() # 后5行 df.columns # 列名 df.index # 行索引 df.axes # 同时显示行列标签 df.sample(2) # 随机查看 n 个样本,replace = True df.shape # 查看形状 df.info() # 查看索引、数据类型和内存信息 df.describe().T # 查看数值型列的汇总统计 df.dtypes # 查看各字段类型,如果不符合就要转化 df["性别"].unique() # 显示某列中的不重复值 df["性别"].value_counts() # 唯一值的记录数 # ② 修改标签 # 我们知道DataFrame是有行列标签,值及表信息组成, df_ = pd.DataFrame(np.random.randint(1,100,(4,3)),index=list("abcd"),columns=list("suv")) df_.index# Index(['a', 'b', 'c', 'd'], dtype='object') df_.columns #Index(['s', 'u', 'v'], dtype='object') df_.values # array([[19, 10, 49], # [84, 7, 28], # [69, 96, 1], # [33, 11, 2]]) # 所以pandas是基于numpy所形成的一种数据结构 # 修改行列标签很简单,可以在加载的时间修改,也可以加载好了之后修改 # df_.rename(columns={},index={}) df.set_index('column_one') # 更改索引列 df.reset_index(drop=True)#恢复位置索引,删除原来的索引 # ③ 转化数据类型 # 1. 数值型 df["a"]=df["a"].astype("int32") # 2. 日期型 df["a"]=df["a"].astype("datetime64[ns]")#numpy 的时间类型 pd.to_datetime(student["s_birth"])# 类时间字符串 import datetime.datetime datetime.datetime(2018, 1, 1) # python 自带时间类型 # ④ 空值重复值异常值的检测 # 1 每列的空值数占比 # df[df.isnull().any(anis=1)] 空值行 (df_.isnull().sum()/df_.shape[0]*100).map(lambda x:str(int(x))+"%") #每列空值占比 # 2 删除整行都是空值的 df_.dropna(how="all") #all和any一行只有一个空值或者全部都是空值的即删除该记录 # 3 填充 # df["法1"]=er["a"].fillna(er["a"].mean())#指定值填充 df_.bfill() #用后面的填充 df_.ffill() #用前面的填充 #分组填充(了解) df4.groupby("sex")["call"].apply(lambda x: x.fillna(x.mean())# 分组填充nan # 还可以用拉格朗日插值法(即多项式插值法),也是很简单的 # ⑤ 重复值 # 1 检测重复值 df_2.duplicated()#检索重复记录,True , df_2.duplicated(["张三","李四"])#指定字段检索重复记录, True df_2.duplicated().sum()# 重复的行数 # 2 删除重复行 df_2.drop_duplicates(ignore_index=True)#重新排列标签2.2 筛选# ① 筛选 #筛选出来的数据,一是作为新数据源再操作,二是查看关键信息 # 数据的类型大致分为三类 1 数值 2 日期(本质也是数值) 3 文本 # 由于query函数中可以灵活的使用各种有利于筛选的函数 df.loc[df["性别"]=="男",["身高","性别"]] #帅选后取另外两列, df[df["性别"]=="男"] #单条件 df[(df["姓名"]=="小明")|(df["姓名"]=="大黑")]# 多条件 #query中的intplace = False(默认不覆盖源数据,生成一个新数据) df.query('性别 =="男"') #单条件 df.query('(性别 == "男") or (年龄 != 25)') #多条件(and or not) 注意单双引号的写法 df.query("sqrt(年龄) > 2") # 年龄的平方根大于2的行 # 上面是关于文本和数值的筛选,下面看下对日期的筛选 df1 = pd.DataFrame(np.arange(24).reshape((6, 4)),columns=['A', 'B', 'C', 'D']) df1["data"]=pd.date_range('20211129', periods=6) df1 #如果提取2021年12月订购日为2或以上的所有订单,可以写成这样 df1.query("data.dt.month ==12 and data.dt.year ==2021 and data.dt.day >=2")# 其他的日期筛选类似 df1.query("data >= '2021-11-15' and data 15") df.loc[df["性别"]=="男",["身高","性别"]] #官方推荐使用这种写法,不推荐df[df["性别"]=="男"]["身高","性别"]2.3 替换# 像在excel中一样,先筛选出来,在替换,然后放回原数据当中,在pandas中就有点笨笨的 #第一步,先筛选数据,比如筛选姓名中还有红字的行 df_hong = df[df["姓名"].str.contains("红")] #第二步,筛选姓名中没有红字的行 df_nothong = df[~df["姓名"].str.contains("红")] #第三步替换姓名有红字的记录中身高为175,年龄为23 df_hong.replace({"身高":{173:175},"年龄":{20:23}},inplace=True) df_hong #第四步纵向合并 df_merge = pd.concat([df_hong,df_nothong]) df_merge #最终结果 # 下面是两种常用的替换格式,其他的可以 ctrl + tab键查看 # df.replace(0, 5) # df.replace({'A': {0: 100, 4: 400}})2.4 分列df_split = pd.DataFrame(["陕西-咸阳","陕西-西安","浙江-杭州"],columns=["地区"]) df_split # 方法1 df_columns_split1=pd.DataFrame([i.split("-") for i in df_split["地区"]], index=df_split.index,columns=["省","市"]) df_columns_split1#得到了分开的两列 #在合并到原来的数据中 # df_merge = pd.concat((df_1,df_columns_split),axis=1)#df_1为原数据 #方法2 df_columns_split2 = df_split["地区"].str.split("-",expand=True) df_columns_split2.rename(columns={0:"省",1:"市"}) # df_merge = pd.concat((df_1,df_columns_split),axis=1)#df_1为原数据2.5 造新列df_new = pd.DataFrame(np.random.randint(10,69,size=(5,2)),index=["张三","李四","王五","赵六","小赵"],columns = ["年龄1","年龄2"]) df_new # excel中有if ifs switch等都可以对数值列重新分段,在pandas中如何造新列 # 分为三种,对数值 对日期 对文本(就是上面的筛选后替换) #第①种对数值列进行重新分段,例如年龄 # 利用映射函数 def age(x): if x>50: return "大于50" elif x>=15: return "[15,50]" else: return "[10,15)" # df_new["年龄1"].map(age).to_frame()#to_frame()将其转化为Dataframe # pd.cut(df_new["年龄1"],bins=4)#分箱 # 弟②中是利用日期列计算其他列 # 年 季 月 周 日 时 分 秒 df_time = pd.date_range(start="2022/11/1",end="2022/12/5") df_time1 = pd.DataFrame(np.random.randint(51,100,size=(35,3)),columns=["数学","英语","语文"]) df_time1.insert(0,"日期",df_time) df_time1 df_month =df_time1["日期"].dt.month #从年 - 秒都可以 # df_time1.insert(1,"月",df_month) df_time1.groupby("月").agg({"数学":np.mean,"语文":max}).round(1)#按时间对数值进行各种各样的聚合 # 对于时间,还有可能要利用两个时间做差,或者距离某一个固定的时间差是多少 # 我想查看30天后的日期,在pandas中不支持直接加30,而需要引入 from datetime import datetime,timedelta df_time1["日期1"] = df_time1["日期"]+timedelta(days=30)#30天后 # 求日期差 df_time1["相差天数"] = df_time1["日期1"]-df_time1["日期"] df_time1["相差天数"]=df_time1["相差天数"].map(lambda x:x.days) df_time1.info()2.6 排序# 11 排序 #1.直接对某一列进行排名 #01 外国式排名 df2["rank_min"]=df2["F"].rank(method="min", ascending=False,na_option="bottom")#中国式排名 na_option="bottom" 将空值排序到最后 #02 连续排名 df2["rank_first"]=df2["F"].rank(method="first", ascending=False,na_option="bottom")#外国式排名 #03 中国式排名 df1["rank_dense"]=df1["A"].rank( method="dense",ascending=False)#1,2,3,4,5 连续排序 #2.分组排名 df1["分组排名"]=df1.groupby("B")["C"].rank(method="min", ascending=False,na_option="bottom")2.7 分组聚合# ① 聚合 df.sum() # 求和 df.count() # 返回每一列中的非空值的个数 df.mean() # 均值 df.median() # 返回每一列的中位数 df.max() # 最大值 df.min() # 最小值 df.corr() # 返回列与列之间的相关系数 df.var() # 方差 df.std() #标准差 df.skew()# 计算偏度 df.kurt()# 计算峰度 df.std() # 返回每一列的标准差 s.mode() # 众数 df.idxmax() # 每列最大的值的索引 df.idxmin() # 最小值 # 累计统计 ds.cumsum() # 前边所有值之和 ds.cumprod() # 前边所有值之积(了解) ds.cummax() # 前边所有值的最大值(了解) ds.cummin() # 前边所有值的最小值(了解) # 作为了解即可---------窗口计算(滚动计算) ds.rolling(x).sum() #依次计算相邻x个元素的和 ds.rolling(x).mean() #依次计算相邻x个元素的算术平均 ds.rolling(x).var() #依次计算相邻x个元素的方差 ds.rolling(x).std() #依次计算相邻x个元素的标准差 ds.rolling(x).min() #依次计算相邻x个元素的最小值 ds.rolling(x).max() #依次计算相邻x个元素的最大值 #同环比(行索引设为日期型,) df["date"].pct_change(periods=1) #同比(相差1行) df["date"].pct_change(periods=12)#环比(相差12行) # ② 分组 #分组聚合核心函数: groupby() 对象的方法 df1.groupby(["A","B"])["C"].agg(len)#按照A B列分组,对C列统计行数, df1.agg([len,max])#不分组就是对全部列操作 df1.groupby(by=["B","C"])["A"].agg((len,sum))#按照B C列分组,对A列统计行数和求和, df1.groupby(by=["B","C"]).agg({"A":[sum,min,max],"B":[sum,min,max]})#分组后,对不同的列可以显示不同的聚合 df1.groupby(["A","B"]).agg(len) # 1.按照谁来分组,2.对全部的列还是对个别的列进行相同的聚合,还是不同的聚合 # 如果要把行索引当成分组依据,可以设置level=0层级,lever是多重行索引的数值索引(层级),如果只有一层索引,lever=0就是按照行索引进行运算的,sort=False 分组运算后升序排列,默认sort=Ture ,不排序 bd=pd.DataFrame([1,2,3,4,5,6],columns=["A"],index=["a","a","b","c","b","a"]) bd.groupby(level=0) # 通过遍历可以发现这个df.groupby("id")是一个分组对象,后面的聚合那就是针对每一个组来操作的, # 要么是这一组中的每一个元素操作,要么是整个组操作3 表的级联# 掌握merge和concat就行了 : 表的级联类比sql, 无非就是 内 左 右 全 (这4个就是横向的)用merge足够,而纵向的用concat就可以了 #① merge df1.merge(df2,how="left/inner/outer",on="A",left_index=True,right_index=True,left_on='lkey', right_on='rkey',suffixes default is (“_x”, “_y”) 重名字段的后缀) 横向 #解释参数: #01 how="left/inner/outer" 连接方式 default 'inner' #02 on="A" 连接的字段(可以是:on=["A","B"])# 前提是连接的字段在左右表中都叫一样的名字,可以进行多字段匹配连接 #03 left_index=True,right_index=True,左右表的行标签作为连接条件 #04 left_on='左列名字', right_on='右列名字' 连接的字段在左右表中叫不一样的名字时,可以自己指定左右表的列名字 #05 suffixes default is (“_x”, “_y”) 左右表重名字段的后缀,用以区别2表中的字段 #② join(了解) df1.join(df2,how="left/inner/outer",on="A",lsuffix='_df22', rsuffix='_df11') 横向 df22.join(df11,how="left",on="A",lsuffix='_df22', rsuffix='_df11') #参数说明: #01 how="left/inner/outer" 连接方式 #02 on="A" 连接的字段(可以是:on=["A","B"])# 前提是连接的字段在左右表中都叫一样的名字,不写时默认为左右表的行标签为连接条件 #03 lsuffix='_df22' 左, rsuffix='_df11' 右 重名字段的后缀,主要和on 条件搭配 #④ concat 只要列名相同,就能实现物理意义上的纵向拼接 pd.concat([df22,df11],ignore_index=True,join="inner/outer",axis=0/1) #没有连接条件 纵向或横向拼接 pd.concat([df22,df11],ignore_index=True) pd.concat((df1,df1),keys=["期中考试","期末考试"])#keys可以创建多层次索引 #参数说明: #01 pd.concat() 写法 numpy中是:np.concatenate() #02 [df22,df11] 列表形式 #03 ignore_index=True 追加后,采取自增长(数值型)行索引的方式,不写默认采取df2原来的行索引,0,1,2,3... #04 join="inner/outer" 默认为inner 解释:inner就是当df1和df2列名不完全相同时,只拼接列名相同的, # outer就是df1和df2列名不完全相同时,拼接列名相同的,列名不相同的另起一列,没有数据的用nan 补齐! default 'outer' #05 axis=0/1 可以横向拼接,也可以纵向拼接 ,0 按行拼接,以列名为参照物, 1 按列拼接,以行名为参照物4 常用函数# map apply applymap transform agg groupby pivot_table(透视表函数) # ① map() 单映射函数(只针对单序列) def main(x): return x**2 df["A"].map(def)#def 是做何种映射的函数 df1["A"].map({0:20})#把A列中所有的0替换成20 # ② apply() 单列多列都可以,用的最多,其效率也高,操作的最小的单位是一行或者一列 df["A"].apply(def)#单列时和map一样,其效率比map高 df.apply(def)#函数可以是内置函数也可以是自定义的函数 # 实例(对DataFrame操作) df_3 = pd.DataFrame([1,2,3,5,46,8]) df_3.apply(np.sum) # ③ applymap() 只针对DataFrame中的每个元素 df_3.applymap(np.sum) #只针对每个元素操作,聚合是没用的 # ④ transform()和 agg()函数 这两函数都是专门的对分组对象操作的函数 df1.groupby(by=df1.index).transform("count")#全部操作 df1.groupby(by=["B","C"]).agg({"A":[sum,min,max],"B":[sum,min,max]})#分组后,对不同的列可以显示不同的聚合 # ⑤ groupby()分组函数 df.groupby(["a列","b列"])["c列"].sum() #按a b列分组对c列求和 df1.groupby(by=["B","C"])["A"].agg((len,sum))#按照B C列分组,对A列统计行数和求和, df1.groupby(by=["B","C"]).agg({"A":[sum,min,max],"B":[sum,min,max]})#分组后,对不同的列可以显示不同的聚合 #具体的看分组聚合部分 # ⑥ pivot_table() pd.pivot_table(df, values='D', index=['A', 'B'],columns=['C'], aggfunc=np.sum, fill_value=0) 01. data=df 数据从哪里来. 02. values 值区域,可选,不写时默认对其他数值列进行 默认:aggfunc='mean' 03. index 行维度,可以是多层的index=['A', 'B'] 04. columns 列维度,可以是多层的index=['C', 'D'] 05. aggfunc=np.sum 对所有的values计算方式为求和 pd.pivot_table(df, values=['D', 'E'], index=['A', 'C'],aggfunc={'D': np.mean,'E': np.sum}) #解释:只有行两层维度,值区域有 D 和 E 列 ,对D列求平均值.对E列求和 还可以对E列:'E': [min, max, np.mean] 06. fill_value=0 在对值计算之前将nan填充为0 07. dropna : bool, default True 对nan值不做计算 08. margins_name="汇总",margins=True 此2个参数确定显示汇总行5 pandas绘图#Pandas的另一个优点是与Matplotlib的集成,可以直接绘制DataFrame和Series。 #可以绘制的图形有 'line' : line plot (default) #01 折线图 - 'bar' : vertical bar plot #02 柱形图 - 'barh' : horizontal bar plot #03 条形图 - 'hist' : histogram #04 频率分布直方图,s1.plot(kind="hist",bins=2,range=[0,10]) bins是将x轴分为几大块 - 'box' : boxplot #05 盒子图(盒须图)s1.plot(kind="box") 和 s1.describe() 对应起来 - 'kde' : Kernel Density Estimation plot # 密度图,和hist图类似,这一区间的值在这一列中所占的百分比 - 'density' : same as 'kde'#密度图,和hist图类似,这一区间的值在这一列中所占的百分比 - 'area' : area plot#面积图 - 'pie' : pie plot #饼图 - 'scatter' : scatter plot #散点图 #散点图,观察2个一维数据序列的关系,df_1.plot(x="python",y="Math",kind="scatter") - 'hexbin' : hexbin plot.''' #1. 数据用Series #一定是将行索引定位x轴 #01 s1.plot(c="blue",title="折线图") #02 s1.plot(kind="bar",c="blue",title="柱形图") #03 s1.plot(kind="hist",bins=2,range=[0,10],title="直方图")#将值按照区间划分,统计个数, #04 s1.plot(kind="box",title="盒子图(盒须图)") ~ s1.describe() #05 s1.plot(kind="kde")#密度图,



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3