; 1 pandas数据读取
Pandas需要先读取表格类型的数据,然后进行分析
1.1 读取文件和基础语句:
读取csv文件数据:
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
ratings=pd.read_csv(filepatch)
print(ratings.head())
print(ratings.shape)
print(ratings.columns)
print(ratings.index)
print(ratings.dtypes)
读取txt文件数据,txt文件需要以行列行使储存数据:
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.txt"
ratings=pd.read_csv(filepatch,sep="\t",header=None,names=['NAME', 'state'])
print(ratings.head())
读取excel文件数据:
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\bhlh112.xlsx"
ratings=pd.read_excel(filepatch)
print(ratings.head())
2 pandas数据结构(dataframe & series)
DataFrame:二维数据,整个表格,多行多列。
Series:一维数据,代表一行或一列。包含一组数据(不同数据类型)和一组与之相关的数据标签(索引)组成。
; 3 创建Series或Dataframe
3.1 series:
3.1.1 列表创建series:
import pandas as pd
sl=pd.Series([1,"A",23,5.4])
print(sl.index)
print(sl.values)
sl=pd.Series([1,"A",23,5.4],index=["a","b","c","d"])
print(sl.index)
3.1.2 字典创建series:
dictdata={"a":123,"b":3234,"c":1.2,"d":"end"}
sl2=pd.Series(dictdata)
print(sl2)
3.1.3 查询Series中的数据
print(sl2["a"])
print(sl2[["a","b"]])
3.2 Dataframe
3.2.1 创建Dataframe:
①.常见的方法为第一章中的Pandas读取excel/csv/mysql
②.使用多个字典文件创建Dataframe
import pandas as pd
dataf={"name":["xiaohong","xiaozhang","xiangqiang"],
"age":[21,23,22],
"gender":["female","male","female"],
"school":["1s","3s","2s"]}
df=pd.DataFrame(dataf)
print(df)
print(df.index)
print(df.columns)
3.2.2 查询Dataframe中的数据:
如果只查询一列、一行,返回的是Series。
如果查询的说多列、多行,返回的是一个Dataframe。
print(df["age"])
print(df[["age"]])
print(df[["age","school"]])
4 pandas数据查询
4.1 loc和iloc的用法
4.1.1 loc
loc 基于行标签和列标签(x_label、y_label)进行索引,主要查询方法:
1.使用单个labe伯查询数据
2.使用值列表批查询
3.使用数伯区间进行范围查询
4.使用条件太达式查向
5.调用函数查询
loc先行后列,中间用逗号(,)分割。
4.1.1.0 数据准备
传入NBA球员薪资情况表:
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
df.set_index("NAME",inplace=True)
df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
4.1.1.1 使用单个label值查询数据
print(df.loc["Stephen Curry, PG","SALSRY"])
print(df.loc["Stephen Curry, PG",["SALSRY","TEAM"]])
4.1.1.2 使用值列表批量查询数据
print(df.loc[["Stephen Curry, PG","James Harden, SG","John Wall, PG"],"SALSRY"])
print(df.loc[["Stephen Curry, PG","James Harden, SG","John Wall, PG"],["SALSRY","TEAM"]])
4.1.1.3 使用数值区间批量查询数据
【区间既包含开始,也包含结束】
print(df.loc["Stephen Curry, PG":"John Wall, PG","SALSRY"])
print(df.loc["Stephen Curry, PG","TEAM":"SALSRY"])
print(df.loc["Stephen Curry, PG":"John Wall, PG","TEAM":"SALSRY"])
4.1.1.4 使用条件表达式查询
【bool列表的长度得等于行数或者列数】
print(df.loc[df["SALSRY"]>41018900,:])
print(df.loc[(df["SALSRY"]>41018900)&(df["TEAM"]=="Los Angeles Lakers"),:])
4.1.1.5 使用函数查询
print(df.loc[lambda df :(df["SALSRY"]>41018900)&(df["TEAM"]=="Los Angeles Lakers"),:])
def choose_maydata(df):
return df["TEAM"]=="Golden State Warriors"
print(df.loc[choose_maydata,:])
4.1.2 iloc
iloc 基于行索引和列索引(index,columns)都是从 0 开始
如果数据的行标签和列标签名字太长或不容易记,则用 iloc 很方便,只需记标签对应的索引即可。
print(df.iloc[0,2])
print(df.iloc[0:2])
print(df.iloc[:,0:2])
print(df.iloc[0:2,0:2])
print(df.iloc[[0,2],[0,1,2]])
5 Pandas新增数据列
【直接赋值/apply/assign/分条件赋值】
5.0 数据预处理
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
5.1 直接赋值
和上文提到的修改数值方法相同,将Series格式看作为dictionary直接赋值。
df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
df.loc[:,"positions_TYPE"]=df["NAME"].str.replace("\w* \w*,","")
df.loc[:,"NAME"]=df["NAME"].str.replace(",.*","")
5.2 df.apply方法
这个函数需要自己实现,函数的传入参数根据axis来定,比如axis = 1,就会把一行数据作为Series的数据结构传入给自己实现的函数中,我们在函数中实现对Series不同属性之间的计算,返回一个结果,则apply函数 会自动遍历每一行DataFrame的数据,最后将所有结果组合成一个Series数据结构并返回。
实例:添加一列实例:薪资大于40000000的为高薪,低于10500000的为底薪,否则就是正常薪资。
def get_SALSRY(df):
if df["SALSRY"]>=40000000:
return "high"
elif df["SALSRY"]10500000:
return "low"
else:
return "normal"
df.loc[:,"hight_low"]=df.apply(get_SALSRY,axis=1)
x=df["hight_low"].value_counts()
print(x)
5.3 df.assign方法
能够同时新增多个列,返回一个新列,该对象除新列外,还包含所有原始列。【assgin不会改变原有df,因此需要重新赋值】
实例:添加一列球员人民币薪资
df=df.assign(RMB=lambda x :x["SALSRY"]*6.72)
5.4 按条件选择分组分别赋值
按条件先选择数据,然后对这部分数据赋值新列
实例:PG球员薪资超过30000000认为是球星。
df["superstar"]=""
df.loc[df["SALSRY"]>=30000000,"superstar"]="star"
df.loc[df["SALSRY"]<30000000,"superstar"]="normal_player"
x=df["superstar"].value_counts()
print(x)
6 Pandas对缺值的处理
三类函数完成以上操作:
●isnll和notnull: 检测是否是空值,可用于df和series。
●dropna: 丢弃、删除缺失值
axis :删除行还是列,{0 or "index', 1 or 'columns’}, default 0
how :如果等于any则任何值为空都删除,如果等于al则所有值都为空才删除。
inplace :如果为True则修改当前df,否则返回新的df。
●fllna: 填充空值
value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)。
method :等于il使用前一个不为空的值填充forword fll;等于bil使用后一个不为空的值填充backword fill。
axis: 按行还是列填充,{0 or index', 1 or 'columns'}
inplace :如果为True则修改当前df,否则返回新的df。
6.0 准备数据
录入qPCR的分析数据(excel):
其中skiprows=num这一参数能够忽略设置的行数,即skiprows=1:忽略第一行。
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\qpcr.xlsx"
df=pd.read_excel(filepatch,skiprows=1)
6.1 检测数据集中的空值
isnull返回的值均为True/False,适用于Dataframe和Series。
print(df.isnull())
print(df["SAMPLE"].isnull())
notull可用于筛选所有不为空值的行列
print(df.notnull())
print(df["SAMPLE"].notnull())
实例:返回”A1″列不为空值的所有行。
print(df.loc[df["A1"].notnull(),:])
6.2 删除空值的列
dropna函数中axis=”columns”表示列删除,how=”all”表示删除全为空值的列,inplace=True表示对数据集本身进行修改。
axis参数:存在”columns”和”index”两种模式。即,一个删除列一个删除行。
how参数:存在”all”和”any”两种模式。使用”all”时删除全部为空值模式;使用”any”时为存在空值就删除模式。
实例:删除全部为空值的列。
df.dropna(axis="columns",how="all",inplace=True)
实例:删除全部为空值的行。
df.dropna(axis="index",how="all",inplace=True)
6.4 填充 空值
使用fillna函数对空值进行填充,需要用到inplace=True对原Dataframe进行修改。
fillna函数原理:【df.loc[:,”A1″]=df[“A1”].fillna(“NA”)】,还类似于字典形式。
对单一Series进行填充
df.fillna({"A1":0},inplace=True)
对多个Series进行填充
df.fillna({"A1":"NA","A2":"NA","A3":"NA","ACT1":"NA","ACT2":"NA","ACT3":"NA"},inplace=True)
6.5 将某列中的空值填充为上一个元素
这里用到了fillna中的参数:ffill(forward fill)。即使用前面不为空的值进行填充。
实例:将NAME和SAMPLE中的缺失值进行填充
df.loc[:,"NAME"]=df["NAME"].fillna(method="ffill")
df.loc[:,"SAMPLE"]=df["SAMPLE"].fillna(method="ffill")
6.6 将清洗好的excel保存为新的文件
使用to_excel将数据保存为新的excel,保存时添加index=False能够避免生成行数列。
df.to_excel(r"C:\Users\radiomumm\Desktop\sucai\qpcr_clean.xlsx",index=False)
除to_excel外还有:
7 Pandas对数据进行排序
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
7.1 Series的排序
Series.sort_ values(ascending=True, inplace=False)
参数:
- ascencding: 默认为True升序排序,为False降序排序。
- inplace: 是否修改原始Series。
排序时对数值和字符串均能排序,数值默认升序,字符串默认a-z。
print(df["SALSRY"].sort_values())
print(df["SALSRY"].sort_values(ascending=False))
print(df["TEAM"].sort_values())
7.2 DataFrame的排序
DataFrame.sort values(by, ascending=True, inplace=False)
参数 :
- by: 字符串或者List
- ascending: bool或者List, 升序还是降序,如果是list对应by的多列。
- inplace: 是否修改原始DataFrame
事实上DF是以某一列或某几列对整个数据集按行排序。
print(df.sort_values(by="SALSRY"))
print(df.sort_values(by="SALSRY",ascending=False))
对df中多列值进行排列【多列排序时谁在前,优先排谁】
print(df.sort_values(by=["TEAM","SALSRY"],ascending=False))
print(df.sort_values(by=["SALSRY","TEAM"],ascending=False))
排序时分别指定升序降序
print(df.sort_values(by=["TEAM","SALSRY"],ascending=[False,True]))
8 Pandas中字符串的处理
pandas提供大量关于字符串常用方法:
https://pandas.pydata.org/docs/reference/series.html#string-handling
具体使用方法 :
- 使用方法:先获取Series的str属性, 然后在属性上调用函数。
- 只能在字符串列上使用,不能数字列上使用。
- Dataframe.上没有str属性和处理方法。
- Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似。
本节只挑选常用的部分语句演示: - 获取Series的str属性,然后使用各种字符串处理函数
- 使用str的startswith、contains等bool类Series可以做条件查询
- 需要多次str处理的链式操作
- 使用正则表达式的处理
8.0 准备数据
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
8.1 替换字符串中的内容
使用replace函数,批量替换series中的特定字符串。
print(df["SALSRY"].str.replace("$","").str.replace(",",""))
8.2 使用str的startswith、contains等得到bool的Series可以做条件查询
condition=df["NAME"].str.startswith("Stephen")
print(df[condition])
8.3 多次替换并截取字符串中的内容
print(df["NAME"].str.replace(", ","-").str.slice(-2))
print(df["NAME"].str.replace(", ","-").str[-2:])
8.4 使用正则表达式的处理
实例:添加一列球员打什么位置
def get_pos(x):
name,pos=x["NAME"].split(",")
return "{} is {}".format(name,pos)
df["infor"]=df.apply(get_pos,axis=1)
问题:如何还原原有的NAME信息?
1.使用替换的方法
df.loc[:,"infor"]=df["infor"].str.replace(" is ",",")
2.使用正则表达式
df.loc[:,"infor"]=df["infor"].str.replace(" \w\w ",",")
Pandas中的axis参数如何理解?
●axis=0或者”index”:
如果是单行操作,就指的是某一行
如果是聚合操作,指的是跨行cross rows
●axis=1或者”columns” :
如果是单列操作,就指的是某一列
■如果是聚合操作,指的是跨列cross columns
按哪个axis,就是这个axis要动起来(类似被for遍历),其它的axis保持不动
创建3*4的dataframe:
import pandas as pd
import numpy as np
df=pd.DataFrame(np.arange(12).reshape(3,4),columns=["a","b","c","d"],index=["A","B","C"])
1.单列drop删除某一列
df.drop("a",axis=1,inplace=True)
2.单行drop,删除某一行
df.drop("A",axis=0,inplace=True)
3.按axis=0/index执行mean聚合操作
【反直觉:输出的不是每行的结果,而是每列的结果】
可以理解为:axis=0即传入行坐标输出的是列标题的结果,而axis=1传入列坐标,输出的是行标题结果。
实例:输出每列平均值
print(df.mean(axis=0))
实例:输出每行平均值
print(df.mean(axis=1))
4.加深理解
实例:新增一列计算平均值
def get_mean_columns(x):
return (x["a"]+x["b"]+x["c"]+x["d"])/4
df["mean1"]=df.apply(get_mean_columns,axis=1)
9 Pandas中的index如何使用
index的用途总结:
- 更方便的数据查询
- 使用index可以获得性能提升
- 自动的数据对齐功能
- 更多更强大的数据结构支持
数据准备:
import time
from sklearn.utils import shuffle
import pandas as pd
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
9.1 使用index查询数据
由于set_index会将索引列删除,因此设置drop=False使其保留在列表内。
9.1.1 设置 index:
df.set_index("TEAM",inplace=True,drop=False)
9.1.2 查询:
- 使用columns的condition的方法查询
condition=df.loc[df["TEAM"]=="Golden State Warriors"]
print(condition)
2.使用index的方法查询,简化查询过程
condition=df.loc["Golden State Warriors"]
print(condition)
9.2 使用index能够提升查询性能
蓝色线:如果index是唯一的,Pandas会使用哈希表优化,查询性能为O(1)。
绿色线:如果index不是唯一的, 但是有序,Pandas会使用二分查找算法,查询性能为O(logN)。
黄色线:如果index是完全随机的,那么每次查询都要扫描全表,查询性能为O(N)。
; 9.2.1 实验1:完全随机的顺序查询
df_shuffle=shuffle(df)
print(df_shuffle.index.is_monotonic_increasing)
print(df_shuffle.index.is_unique)
start=time.time()
print(df_shuffle.loc["Cleveland Cavaliers"])
end=time.time()
print('Running time: %s Seconds'%(end-start))
9.2.2 实验2:将index排序后查询
df_shuffle_sorted=df_shuffle.sort_index()
print(df_shuffle_sorted.index.is_monotonic_increasing)
print(df_shuffle_sorted.index.is_unique)
start=time.time()
print(df_shuffle_sorted.loc["Cleveland Cavaliers"])
end=time.time()
print('Running time: %s Seconds'%(end-start))
9.3 使用Series能够自动对齐数据
实例:两个series相加,相同索引相加,不相同的为NA。
s1=pd.Series([1,2,3,4],index=["a","b","c","d"])
s2=pd.Series([4,5,6,7,8],index=["c","d","f","w","q"])
print(s1+s2)
输出为:
a NaN
b NaN
c 7.0
d 9.0
f NaN
q NaN
w NaN
9.4 使用index更多更强大的数据结构支持
很多强大的索引数据结构
●Categoricallndex,基于分类数据的Index,提升性能;
●MutiIndex, 多维索引,用于groupby多维聚合后结果等;
●DatetimeIndex, 时间类型索引,强大的日期和时间的方法支持;
10 Pandas中merge的使用方法
Pandas的Merge,栖当于Sql的Join, 将不同的表按key关联到一个表。
merge的语法:
【pd.merge(left, right,how=”inner”,on=None,left_on=None,right_on=None,left_index=False,right_ndex=False,sort=True,suffixes=(“_x”,”_y”),copy=True,indicator=False,validate=None)】
●left/right: 要merge的dataframe或者有name的Series
●how: join类型, “left, ‘right, ‘outer’ , ‘inner’,默认为”inner”
●on: join的key, left和right都需要有这个key
●left_on: left的dataframe或者Series的key
●right_on: right的dataframe或者Series的key
●left_index/right_index: 使用index而不是普通的column做jion
●suffixes: 两个元素的后缀,如果列有重名,自动添加后缀,默认是(“_x”,”_y”)
10.1 数据集merge的使用实例
使用网站MovieLens | GroupLens提供的电影评分数据:
输入数据:
10.1.0 数据的预处理,读取csv文件数据
import pandas as pd
df_ratings=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",sep="::",engine="python",names="User_id::Movie_id::Ratings::Timestamp".split("::"))
df_users=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\users.dat",sep="::",engine="python",names="User_id::Gender::Age::Occupation::Zip-code".split("::"))
df_movies=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\movies.dat",sep="::",engine="python",names="Movie_id::Title::Genres".split("::"))
print(df_movies.head(20))
print(df_users.head(20))
print(df_ratings.head(20))
10.1.1 Pandas中merge的使用方法
1.处理评分(df_ratings)与用户(df_users)之间的join。
left_on/right_on指的是按照两个数据集的指定key合并,how=”inner”表示两组数据均包含选取key才保留。
df_ratings_users=pd.merge(df_ratings,df_users,left_on="User_id"
,right_on="User_id"
,how="inner")
print(df_ratings_users.head(20))
2.处理评分用户(df_ratings_users)与电影信息(df_movies)之间的join。
df_ratings_users_movies=pd.merge(df_ratings_users,df_movies,left_on="Movie_id"
,right_on="Movie_id"
,how="inner")
print(df_ratings_users_movies.head(120))
10.2 Pandas中merge的数据对齐关系
以下关系要正确理解:
●one-to-one:一对一关系,关联的key都是唯一的。
■比如(学号,姓名) merge (学号,年龄),结果条数为: 1*1
●one-to-many:一对多关系, 左边唯一key, 右边不唯一key。
■比如(学号,姓名) merge (学号, [语文成绩、数学成绩、英语成绩),结果条数为: 1*N
●many-to-many:多对多关系,左边右边都不是唯一的。
比如(学号,[语文成绩、数学成绩、英语成绩]) merge (学号, [篮球、足球、乓球]),结果条数为: M*N
实例:
10.2.1 one-to-one一对一关系的merge
left=pd.DataFrame({"sno":[232,211,231,413],
"age":[21,23,22,24]})
right=pd.DataFrame({"sno":[232,211,231,413],
"name":["xiaoz","xiaos","xiaow","xiaod"]})
pd_sum=pd.merge(right,left,on="sno")
print(pd_sum)
10.2.2 one-to-many一对多关系的merge
left=pd.DataFrame({"sno":[232,211,231,413],
"name":["xiaoz","xiaos","xiaow","xiaod"]})
right=pd.DataFrame({"sno":[232,232,232,211,211,211,231,231,231,413],
"grade":["语文99","数学92","英语87","语文92","数学32","英语17",
"语文29","数学34","英语27","英语97"]})
pd_sum=pd.merge(right,left,on="sno")
print(pd_sum)
10.2.3 many-to-many多对多关系的merge
left=pd.DataFrame({"sno":[232,211,211,231,231,231,413],
"爱好":["篮球 ","篮球","排球","台球","电竞","看球","游戏"]})
right=pd.DataFrame({"sno":[232,232,232,211,211,211,231,231,231,413],
"grade":["语文99","数学92","英语87","语文92","数学32","英语17",
"语文29","数学34","英语27","英语97"]})
pd_sum=pd.merge(right,left,on="sno")
print(pd_sum)
10.3 如何理解left join、right join、inner join和outer join的区别
left join:以左边数据集为准,左数据集完全保留,右边数据集为空。
right join:右边数据集完全保留,左边数据集为空。
inner join:左右数据集交集。
outer join:左右数据集合集。
实例:
import pandas as pd
left=pd.DataFrame({"key":["K1","K2","K3","K4"],
"爱好1":["篮球 ","篮球","排球","台球"],
"B":["B1","B2","B3","B4"]})
right=pd.DataFrame({"key":["K3","K4","K5","K6"],
"爱好2":["篮球1 ","篮球2","排球3","台球4"],
"A":["A1","A2","A3","A4"]})
1.inner join,默认【左右两个数据集都存在时才输出】
print(pd.merge(left,right,how="inner"))
2.left join,【左边的都会出现在结果里,右边的如果无法匹配则为Null】
print(pd.merge(left,right,how="left"))
3.right join,【右边的都会出现在结果里,左边的如果无法匹配则为Null】
print(pd.merge(left,right,how="right"))
4.outer join,【左右两个数据集都会出现在结果里,匹配不上的为Null】
print(pd.merge(left,right,how="outer"))
10.4 如果出现非Key的字段重名怎么办
实例 :
import pandas as pd
left=pd.DataFrame({"key":["K1","K2","K3","K4"],
"爱好":["篮球 ","篮球","排球","台球"],
"B":["B1","B2","B3","B4"]})
right=pd.DataFrame({"key":["K3","K4","K5","K6"],
"爱好":["篮球1 ","篮球2","排球3","台球4"],
"A":["A1","A2","A3","A4"]})
Pandas默认处理方法:会在 相同key后加上”_x”和”_y”
print(pd.merge(left,right,on="key"))
可以指定后缀:
print(pd.merge(left,right,on="key",suffixes=("_left","_right")))
11 Pandas实现数据的合并concat
批量合并相同格式的Excel、给DataFrame添加行、 给DataFrame添加列。
一句话说明concat语法:
●使用某种合并方式(innerlouter)
●沿着某个轴向(axis=0/1)
●把多个Pandas对象(DataFrame/Series)台并成一个。
11.1 使用Pandas.concat合并数据
concat语法:
pandas.concat(objs, axis=0, join= “outer”, ignore_ index=False)
●objs:一个列表,内容可以是DataFrame或者Series,可以混合
●axis:默认是0代表按行合并,如果等于1代表按列合并
●join: 合并的时候索引的对齐方式,默认是outer join, 也可以是inner join
●ignore. index: 是否忽略原来來的数据索引。
11.1.0 数据准备
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
df1=pd.DataFrame({"A":["A0","A1","A2","A3","A4","A5"],
"B":["B0","B1","B2","B3","B4","B5"],
"C":["C0","C1","C2","C3","C4","C5"],
"D":["D0","D1","D2","D3","D4","D5"],
"E":["E0","E1","E2","E3","E4","E5"],})
df2=pd.DataFrame({"A":["A10","A11","A12"],
"B":["B10","B11","B12"],
"C":["C10","C11","C12"],
"D":["D10","D11","D12"],
"E":["E10","E11","E12"],
"F":["F10","F11","F12"],})
11.1.1 相同字段的首位相接,对应不上的的列会自动补充为Null
concat默认参数为:axis=0,join=outer,ignore_index=False
dfs=[df1,df2]
df_sum=pd.concat(dfs)
print(df_sum)
df_sum=pd.concat(dfs,keys=["一月","二月"])
print(df_sum)
df_sum=pd.concat(dfs,ignore_index="True")
print(df_sum)
df_sum=pd.concat(dfs,ignore_index="True",join="inner")
print(df_sum)
11.1.2 横向表格合并(行对齐),对应不上的的行会自动补充为Null
df_sum=pd.concat(dfs,axis=1)
print(df_sum)
11.1.3 此外该功能类似于传入新列
s1=pd.Series(list(range(4)),name="G")
df_sum=pd.concat([df1,df2,s1],axis=1)
print(df_sum)
s2=df1.apply(lambda x:x["A"]+"_CG",axis=1)
s2.name="H"
df_sum=pd.concat([df1,s2,s1],axis=1)
print(df_sum)
11.2 使用append()合并数据
append语法:
DataFrame.append(other, ignore_index=False)
append只有按行合并,没有按列合井.相当于concat按行的简形式。
●other: 单个datafrema、 series、 dict, 或者列表
●ignore_ index: 是否忽略掉原来的数据索引
11.2.0 数据准备
df1=pd.DataFrame({"A":[1,2],
"B":[3,4]})
df2=pd.DataFrame({"A":[5,6],
"B":[7,8]})
11.2.1 使用append函数对一个DF添加另一个DF
df_sum=df1.append(df2,ignore_index=True)
print(df_sum)
11.2.2 如何一行一行给DF新增数据
低性能版本,使用for循环【df每次都会重新赋值,如果数据很多会造成卡死】
df=pd.DataFrame(columns=["A"])
for i in range(5):
df=df.append({"A":i},ignore_index=True)
print(df)
高性能版本,使用for循环
df=pd.concat([pd.DataFrame([i],columns=["A"])for i in range(5)],ignore_index=True)
print(df)
如何理解merge( )、concat( )和append( ) 三个函数间的区别?
Pandas提供了concat,merge,join和append四种方法用于dataframe的拼接,其区别如下:
详见:(13条消息) Pandas拼接操作(concat,merge,join和append)的区别_Yale曼陀罗的博客-CSDN博客_concat和append的区别
; 12 Pandas批量拆分与合并Excel文件
实例:
1.将一个大的Excel拆分成多个Excel
2.将多个小Excel合并成一个大的Excel并记录来源
12.0 准备数据,
12.0.1 创建工作文件夹和存放文件夹
work_dir="C:/Users/radiomumm/Desktop/sucai"
splits_dir=f"{work_dir}/splits"
import os
if not os.path.exists(splits_dir):
os.mkdir(splits_dir)
pass
12.0.2 读取Excel到Pandas
import pandas as pd
df_source=pd.read_excel(r"C:\Users\radiomumm\Desktop\sucai\SNP_choose.xlsx",sheet_name="ALL")
print(df_source.index)
print(df_source.shape)
12.1 将一个大的excel拆分为多个小excel
① 使用df.iloc方法,将一个大的daframe, 拆分成多个小dataframe
② 将使用dataframe.to_ excel保存每个小Excel
12.1.1 计算拆分后的每个excel的行数
user_names=["A","B","C","D","E","F","G"]
split_size=df_source.shape[0]//len(user_names)
if df_source.shape[0]%len(user_names)!=0:
split_size+=1
pass
12.1.2 拆分成为多个dataframe
df_subs=[]
for idx,user_name in enumerate(user_names):
begin=idx*split_size
end=begin+split_size
df_sub=df_source.iloc[begin:end]
df_subs.append((idx,user_name,df_sub))
12.1.3 拆分成为多个dataframe
for idx,user_name,df_sub in df_subs:
filename=f"{splits_dir}/aaaaa_{idx}_{user_name}.xlsx"
df_sub.to_excel(filename,index=False)
pass
12.2 将多个小的excel合并为一个大excel
12.2.1 遍历文件夹,得到要合并的Excel文件列表
import os
import pandas as pd
excel_names=[]
splits_path=r"C:\Users\radiomumm\Desktop\sucai\splits"
for excel_name in os.listdir(splits_path):
excel_names.append(excel_name)
12.2.2 分别读取到dataframe,给每个df添加一列用于标记来源
df_list=[]
for excel_name in excel_names:
excel_path=f"{splits_path}/{excel_name}"
df_split=pd.read_excel(excel_path)
username=excel_name.replace("aaaaa_","").replace(".xlsx","")[2:]
df_split["username"]=username
df_list.append(df_split)
pass
12.2.3 使用pd.concat进行df批量合并
df_concat.to_excel(r"C:\Users\radiomumm\Desktop\sucai\df_concat.xlsx",index=False)
- Pandas怎样实现groupby分组统计
类似SQL:
select city.max(temperature) from city. weather group by city
groupby:先对数据分组,然后在每个分组上应用聚合函数、转换函数。
本次演示:
一、分组使用聚 合函数做数据统计
二、遍历groupby的结果理解执行流程
三、实例分组探索NBA数据
13.0 数据准备
import pandas as pd
import numpy as np
filepatch=r"C:\Users\radiomumm\Desktop\sucai\nba.csv"
df=pd.read_csv(filepatch)
df.loc[:,"SALSRY"]=df["SALSRY"].str.replace("$","").str.replace(",","").astype("int32")
def get_pos(x):
name,pos=x["NAME"].split(",")
return pos
df["infor"]=df.apply(get_pos,axis=1)
13.1 分组使用聚合函数做数据统计
13.1.1 单个列groupby,查询所有数据列统计
df.groupby("TEAM").sum()
- groupby中”TEAM”列成为数据的索引列。
- sum函数会将df中的数字形式列按列合并,字符串格式自动忽略。
13.1.2 多个列groupby,查询所有数据列统计
groupby中”TEAM”列和”infor”列成为数据的多级索引列。
df.groupby(["TEAM","infor"]).sum()
去除索引,变为普通的列
df.groupby(["TEAM","infor"],as_index=False).sum()
13.1.3 同时查看多种数据统计
df.groupby("TEAM").agg([np.sum,np.mean,np.std])
查看特定数据列的统计情况
df.groupby("TEAM")["SALSRY"].agg([np.sum,np.mean,np.std])
或者
df.groupby("TEAM").agg([np.sum,np.mean,np.std])["SALSRY"]
13.1.4 不同列使用不同的聚合函数
df.groupby("TEAM").agg({"RK":np.sum,"SALSRY":np.mean})
13.2 遍历groupby
13.2.1 遍历单个列聚合的分组
team=df.groupby("TEAM")
print(team)
以上格式可以直接使用for遍历
for teamid,infor in team:
print(teamid)
print(infor)
使用get_group函数获取单个分组
team.get_group("Denver Nuggets")
13.2.2 遍历多个列聚合分组
team=df.groupby(["TEAM","infor"])
for teamid,inforpos in team:
print(teamid)
print(inforpos)
可以看到,teamid是一个元组,包含了分组情况。
使用get_group函数获取单个分组
team.get_group(("Denver Nuggets"," PG"))
查询group后的某几列,生成Series或者DF
print(team["RK"])
for teamid,inforpos in team["RK"]:
print(teamid)
print(inforpos)
13.3 实例:
1.按照队伍分类后查看每队最高薪球员,并画出柱状图
plt.xticks(rotation=90)设置x轴 标签倾斜度,plt.show( )用于显示。
import matplotlib.pyplot as plt
moneymax=df.groupby("TEAM",as_index=False)["SALSRY"].max()
x=moneymax["TEAM"]
y=moneymax["SALSRY"]
plt.figure(figsize=(10,6))
plt.bar(x,y,width=0.5,align="center",alpha=0.8)
plt.xticks(rotation=90)
plt.show()
2.按照队伍分类后查看每队最高、低薪球员和排名总和,并画出折线图
data=df.groupby("TEAM").agg({"RK":np.sum,"SALSRY":[np.max,np.min]})
plt.plot(data)
plt.xticks(rotation=90)
plt.legend()
plt.show()
data.plot()
plt.xticks(rotation=90)
plt.show()
14 Pandas的分层索引Multilndex的应用
为什么要学习分层索引Mutilndex?
●分层索引:在一个轴向上拥有多个索引层级,可以表达更高维度数据的形式。
●可以更方便的进行数据筛选,如果有序则性能更好。
●groupby等操作的结果,如果足多KEY,结果是分层索引,需要会使用。
●一般不需要白己创建分层索引(Multilndex有构造函数但一般不用)
本次演示提纲:
一、Series的分层索引Multilndex
二、Series有多层索引怎样筛选数据?
三、DataFrame的多层索引Multilndex
四、DataFrame有多层索引怎样筛选数据?
14.0 数据准备
从https://cn.investing.com/网站下载多个公司股票信息,并合并为一个csv文件:
import pandas as pd
workdir="C:/Users/radiomumm/Desktop/sucai"
dfbaba_path=f"{workdir}/groupby/BABA历史数据.csv"
dfbilbil_path=f"{workdir}/groupby/BILI历史数据.csv"
dfbaidu_path=f"{workdir}/groupby/BIDU历史数据.csv"
dfjd_path=f"{workdir}/groupby/JD历史数据.csv"
dfnf_path=f"{workdir}/groupby/NFLX历史数据.csv"
dfbaba=pd.read_csv(dfbaba_path)
dfbilbil=pd.read_csv(dfbilbil_path)
dfbaidu=pd.read_csv(dfbaidu_path)
dfjd=pd.read_csv(dfjd_path)
dfnf=pd.read_csv(dfnf_path)
dfbaba.loc[:,"名字"]="baba"
dfbilbil.loc[:,"名字"]="bilbil"
dfbaidu.loc[:,"名字"]="baidu"
dfjd.loc[:,"名字"]="jingdong"
dfnf.loc[:,"名字"]="nelfx"
dfs=[dfbaba,dfbaidu,dfbilbil,dfjd,dfnf]
dfall=pd.concat(dfs,ignore_index=True)
dfall.to_csv(f"{workdir}/groupby/汇总.csv",encoding="gbk",index=False)
查看数据基本信息 :
print(dfall.shape)
print(dfall["名字"].unique())
print(dfall.index)
14.1 series的分层索引Multilndex
使用groupby函数分组
ser=dfall.groupby(["名字","日期"])["收盘"].mean()
print(ser)
print(ser.index)
使用unstack函数降低索引层次,将二级或次级索引变为列,原本的series变为dataframe。
ser.unstack()
使用reset_index函数将分组索引还原,变为dataframe,前两列为多层搜索引,后一列为索引的值列。
ser.reset_index()
14.2 series存在多层索引Multilndex怎样筛选
使用loc函数进行索引,可以索引第一层或多层。
print(ser.loc["bilbil"])
print(ser.loc["bilbil","2022年5月2日"])
跳过第一层筛选第二层时需要以下两种格式
print(ser.loc[:,"2022年5月2日"])
print(ser.loc[slice(None),"2022年5月2日"])
14.3 Dataframe的多层索引Multilndex
使用set_index对Dataframe进行分层索引
dfall.set_index(["名字","日期"],inplace=True)
print(dfall)
对索引进行排序,先按照第一层索引排序
dfall.sort_index(inplace=True)
print(dfall)
14.4 Dataframe存在多层索引Multilndex怎样筛选
【重点理解】:
●元组(key1,key2)代表筛选多层索引,其中key1是索引第一级, key2是第二级, 比如key1=”jingdong”, key2=”2019-10-02″
●列表[key1,key2]代表同- 层的多个KEY,其中key1和key2是并列的同级索引,比如key1=”jingdong”, key2=”BIDU”
14.4.1常规筛选两个层级
只筛选第一层的某个值
print(dfall.loc["baidu"])
筛选多层索引的所有列,传入元组
print(dfall.loc[("baidu","2022年5月6日"),:])
筛选多层索引的特定列,传入元组
print(dfall.loc[("baidu","2022年5月6日"),"交易量"])
14.4.2 同层的并列筛选
同一层多个索引值的筛选,取出两个对像
print(dfall.loc[["baidu","bilbil"],:])
混合筛选,两个第一层索引值和一个第二层索引值
print(dfall.loc[(["baidu","bilbil"],"2022年5月6日"),:])
混合索引只输出一列
print(dfall.loc[(["baidu","bilbil"],"2022年5月6日"),"涨跌幅"])
多层混合
print(dfall.loc[(["baidu","bilbil"],["2022年5月5日","2022年5月6日"]),"涨跌幅"])
需要只对第二层索引进行筛选,保留一层索引的方法
print(dfall.loc[(slice(None),["2022年5月5日","2022年5月6日"]),"涨跌幅"])
恢复索引为普通的列
dfall.reset_index(inplace=True)
print(dfall)
15 Pandas的数据转换函数map、apply、applymap
数据转换函数对比: map、apply、 aplymap:
- map:只用于Series,实现每个值->值的映射。
- apply:于Series实现每个值的处理,用于Dataframe实现某个轴的Series的处理。
- applymap:只能用于DataFrame,用于处理该DataFrame的每个元素。
15.1 map用于Series值的转换
实例:将股票代码转换成中文名字
15.1.0 数据准备
Series.map(dict)或者Serise.map(function)均可。
from ast import Lambda
import pandas as pd
path=r"C:\Users\radiomumm\Desktop\sucai\groupby\汇总.csv"
df=pd.read_csv(path,encoding="gbk")
print(df.head(20))
print(df["名字"].unique())
准备字典
dict_company_name={"BAIDU":"百度",
"BABA":"阿里巴巴",
"BILBIL":"哔哩哔哩",
"JINGDONG":"京东",
"NELFX":"奈飞"}
15.1.1 map函数用于Series的转化
方法一:map函数传递一个dict
df['公司']=df["名字"].str.upper().map(dict_company_name)
print(df.head(20))
方法二:map函数传入一个函数【function的参数时series的每个元素值】
df['公司']=df["名字"].map(lambda x:dict_company_name[x.upper()])
print(df.head(20))
15.2 apply用于Series和Dataframe的转化
●Series.apply(function),函数的参数是series每个值,与series的map函数十分相似
df['公司']=df["名字"].apply(lambda x:dict_company_name[x.upper()])
print(df.head(20))
●DataFrame.apply(function),函数的参数是Series
df['公司']=df.apply(lambda x:dict_company_name[x["名字"].upper()],axis=1)
print(df.head(20))
【tips】:
apply是在Dataframe中调用;
Lambda的参数x是series,由于指定了asix=1所以Series的key是列名,可以用下x[“”]获取
15.3 applymap用于Dataframe所有值的转化
实例:
将收盘、开盘、高、低、交易量的小数改为整数
sub_df=df[["收盘","开盘","高","低","交易量"]]
sub_df.loc[:,"交易量"]=df["交易量"].str.replace("M","").astype("float64")
sub_df.applymap(lambda x:int(x))
print(sub_df)
对原有Dataframe值进行批量修改
df.loc[:,["收盘","开盘","高","低","交易量"]]=sub_df.applymap(lambda x:int(x))
print(df)
16 Pandas怎样对每个分组(groupby)应用apply函数
补充:
1.Pandas的Groupby遵从三个模式,split、apply、combine模式。
事实上Split就是Pandas中的groupby,apply函数由我们自己控制,可以是一个内置函数也可以自己定义,apply返回值再由Pandas进行combine(拼接)获得输出结果。
2.归一化就是把数据经过处理后使之限定在一定的范围内。比如通常限制在区间[0, 1]或者[-1, 1]
groupby.apply(function)
- function的第一个参数为Dataframe
- 自己写函数的话function返回结果可以是df、series、单个值,甚至和输入的Dataframe没有关系。
; 16.1 实例演示:
1.怎样对数值列按分组进行归一化?
演示:用户对电影评分的归一化
16.1.0 数据准备
import pandas as pd
ratings=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",
sep="::",
engine="python",
names="User_id::Movie_id::Ratings::Timestamp".split("::"))
print(ratings.head())
16.1.1 按照用户id分类,并实现归一化
def ratings_norm(df):
min_value=df["Ratings"].min()
max_value=df["Ratings"].max()
df["ratings_norm"]=df["Ratings"].apply(
lambda x:(x-min_value)/(max_value-min_value))
return df
ratings=ratings.groupby("User_id").apply(ratings_norm)
print(ratings[ratings["User_id"]==1].head())
16.1.2 怎样取每个分组的TOPN数据?
def get_topN(df,topn):
return df.sort_values(by="Ratings")[["User_id","Ratings"]][-topn:]
print(ratings.groupby("User_id",as_index=False E ).apply(get_topN,2).head(20))
17 Pandas的stack和pivot实现数据透视
将列式数据变成二维交叉形式,便于分析,叫做重塑或透视
左侧列表有利于数据增减,而右侧 数据利于数据处理和查找。
; 17.1 stack、unstack、pivot的语法
stack: DataFrame.stack(level=-1, dropna=True),将columh变成index,类似把横放的书籍变成竖放。
level=-1代表多层索引的最内层,可以通过==0、1、 2指定多层索引的对应层。
unstack: DataFrame.unstack(level=-1, fill value=None), 将index变成column,类似把竖放的书籍变成横放 。
pivot: DataFrame.pivot(index=None, columns=None, values=None),指定index、columns. values实现二维透视。
实例:统计得到”电影评分数据集”,每个月份的每个分数被评分多少: (月份、 分数1~5、次数)
17.0 数据准备
import pandas as pd
import numpy as np
df=pd.read_csv(r"C:\Users\radiomumm\Desktop\sucai\ml-1m\ratings.dat",
sep="::",
engine="python",
names="User_id::Movie_id::Ratings::Timestamp".split("::"))
17.2 经过统计得到多维度指标数据
对日期进行处理
df["pdata"]=pd.to_datetime(df["Timestamp"],unit="s")
实现数据统计,dt.month是按月份分组
df_groupby=df.groupby([df["pdata"].dt.month,"Ratings"])["User_id"].agg(pv=np.sum)
以上格式想要绘制横坐标为月份纵坐标为评分次数趋势是无法实现的,需要变化每个评分为一列才能实现
17.3 使用unstack实现数据维透视
df_stack=df_groupby.unstack()
print(df_stack.head(20))
import matplotlib.pyplot as plt
df_stack.plot()
plt.show()
df_unstack=df_stack.stack()
17.4 使用pivot简化透视
df_reset=df_groupby.reset_index()
df_pivot=df_reset.pivot("pdata","Ratings","pv")
Original: https://blog.csdn.net/weixin_48994367/article/details/124848794
Author: Radiomumm
Title: Python pandas模块
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/694354/
转载文章受原作者版权保护。转载请注明原作者出处!