NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。其基本运算对象是一个N维数组对象 ndarray。
- 导入Numpy:import numpy as np
(1)直接构建
- 用法:arr = np.array([[1,2],[3,4]],dtype=np.int32)
(2)arange构建
- 与range()不同,arange()产生的是数组,而range()是一个迭代器
- 形式:arange(start,end,step),区间和步进都可以是浮点数
- 用法:arr2 = np.arange(1.5,3,0.1)
(3)linespace构建
- 形式:np.linspace(start,end,cnt),给出的是区间内数据的个数,而不是步进,以此对区间做等分。另外,它的区间是左右闭区间。除非使用参数endpoint=False
- 用法:arr3 = np.linspace(1,10,20)
(4)zeros 全零构建
- 用法: arr4 = np.zeros((3,4),dtype=np.int32)
(5)ones 全一构建
- 用法:arr5 = np.ones((3,4),dtype=np.int32)
(6)eye 单位矩阵构建
- 用法: arr6 = np.eye(5,dtype=np.int32)
(7)empty()产生一个空的数组,其中的元素值是任意的
arr7 = np.empty((2,3),dtype=np.int32)
arr7.fill(10) #fill填充元素
print(arr7)
(1)ndarray.ndim 维度
(2)ndarray.shape 形状tuple
(3)ndarray.size 元素总数
(4)ndarray.dtype 元素数据类型
(2)ndarray.T 矩阵转置
arr = np.array([[1,2,3],[4,5,6],[7,8,9],[0,1,2]],dtype=np.int32)
print(arr.ndim) #维度
print(arr.shape) #形状tuple
print(arr.size) #元素总数
print(arr.dtype) #元素数据类型
arr2 = arr.reshape((3,4)) #改变形状
print(arr2)
arr3 = arr.T #求转置
print(arr3)
arr4 = arr.ravel() #扁平化数组(展成一维)
print(arr4)
(1)对应位置运算(两数组维度相同时): +、-、*、/、%
注意:某些操作(例如+=和 *=)会直接更改被操作的矩阵数组而不会创建新矩阵数组
a = np.array([[1,2,3],[4,5,6]],dtype=np.int32)
b = np.array([[4,5,6],[1,2,3]],dtype=np.int32)
c = a - b
print(c)
(2)广播运算(当两数组维度不同时):让所有输入数组都向其中形状最长的数组看齐,形状中不足的部分都通过在前面加 1 补齐
a = np.array([[1,2,3],[4,5,6]],dtype=np.int32)
c = np.array([7,8,9])
print(a * c)
'''
[[1,2,3], [[7,8,9],
[4,5,6]] * [7,8,9]]
'''
(1)一维切片
(2)多维切片
4.数组切片
#(1)一维切片:和list的切片长的一样(切片是数据复制行为)
od = np.array([21000, 21180, 21240, 22100, 22400])
c = od[1:] - od[:-1] #可以这样计算每天的旅程
print(c)
#(2)多维切片
arr = np.array([[1,2,3],[4,5,6],[7,8,9],[0,1,2]],dtype=np.int32)
print(arr[:2,2])
print(arr[1,2])
print(arr[1:,1:3])
print(arr[1,...]) #三个点( ... )表示产生完整索引元组所需的冒号 = arr[1] = arr[1,:]
(1)数组索引(传入下标数组)
- 一维数组:索引数组元素表示下标,并根据索引数组样式组成新矩阵- 多维数组:数组索引
a.取多行组成的新二维数组
b.取对应位置元素组成新的一维数组
c.取对应位置元素组成新的二维数组
#(1)数组索引(传入下标数组)
# - 一维数组:索引数组元素表示下标
a = np.arange(12)**2 # the first 12 square numbers
i = np.array( [ 1,1,3,8,5 ] ) # 下标取值一维数组
print(a[i])
j = np.array( [ [ 3, 4], [ 9, 7 ] ] ) # 下标取值并构成二维数组
print(a[j])
# -多维数组:数组索引
palette = np.array( [ [0,0,0],
[255,0,0],
[0,255,0],
[0,0,255],
[255,255,255] ] )
# #取多行组成的新二维数组
index = [0,2,4]
print(palette[index])
# #取对应位置元素组成新的一维数组
index = [[0,1,2],[0,1,2]]
print(palette[index])
# #取对应位置元素组成新的二维数组
rows = [[0,0],[3,3]]
cols = [[0,2],[0,2]]
print(palette[rows,cols])
(2)ndarray索引(传入下标ndarray)
#(2)ndarray索引(传入下标ndarray)
# -多维数组:nadrry索引
# #取多行组成的新二维数组
index = np.array([0,2,4])
print(palette[index])
# #组成新三维数组(第0行和第2行组成的新二维数组+#第0行和第4行组成的新二维数组)(区别!)
image = np.array([ [0,2],
[0,4] ])
print(palette[image])
# #对应位置取元素组成二维数组
i = np.array( [ [0,1],
[1,2] ] )
j = np.array( [ [2,1],
[2,2] ] )
print(palette[i,j])
# #对应位置取元素组成一维数组
i = np.array( [0,1,2,3] )
j = np.array( [0,1,2,0] )
print(palette[i,j])
(3)布尔索引 :使用布尔数组筛选数据(为True的会被保留)
#(3)布尔索引 :使用布尔数组筛选数据(为True的会被保留)
#筛选一维数据
x = np.array([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])
print (x[x > 5])
#筛选多维数据
a = [True,False,False,True] #行筛选
b = [True,False,True] #列筛选
print(x[a,b])
#6.数组遍历(元素全为拷贝)
x = np.array(range(20)).reshape((5,4))
for row in x:
print("每一行: ",row)
for data in row:
print(data)
#想要对数组中的每个元素执行操作,可以使用flat属性,该属性是数组的所有元素的迭代器
for element in x.flat:
print(element,end=",")
#7.矩阵运算
#(1)叉乘 dot :要求a的列数和b的行数相同
a = np.array([[1,3,2],
[4,0,1]])
b = np.array([[1,3],
[0,1],
[5,2]])
c = a.dot(b)
print(c)
#(2)矩阵类型
# 使用np.matrix()将多维列表转换成matrix类型,或使用np.mat()生成矩阵,则所产生的矩阵做*乘法就是点乘
m = np.matrix(a)
print(m.T) #转置
print(m.I) #逆矩阵
print(m.A) #转为ndarry
#8.数学函数
#(1)通用函数:这些函数在数组上按元素进行运算,产生一个数组作为输出 如:sin,cos,tan,exp,floor向下取整,ceil向上取整,sqrt开根号
a = np.array([[1,3,2],
[4,0,1]])
print(np.sqrt(a))
print(np.sin(a))
#(2)算术统计函数:sum()、min()、max()、median()、mean()、average()、std()和val()函数可以求和、最小值、最大值、中位数、平均数、加权平均数、标准差和方差
# -不指定轴:默认求全部
# -指定轴axis:在某个轴上求值
print(np.sum(a))
print(np.sum(a,axis=0))
print(a.sum())
print(a.sum(axis=0))
Pandas 库是一个免费、开源的第三方 Python 库,是 Python 数据分析必不可少的工具之一,它为 Python 数据分析提供了高性能,且易于使用的数据结构,即 Series (一维数组结构)和 DataFrame(二维数组结构)。其特点如下:
(1)Pandas 一个强大的分析结构化数据的工具集,基础是 Numpy(提供高性能的矩阵运算)。
(2)Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。
(3)Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。
1.数据读取(以excel表格:.xls .xlxs为例)pd.read_excel() 参数说明:
(1)io:"D:\datasets\score.xls" 读取文件位置
(2)sheet_name:默认为0
-int : 表示加载第几个子表
-str : 表示加载指定名称的表
-list of int/str:返回多张表组成的字典dict
-None:返回全部表格字典
(3)header:指定表头行号(即表头是哪一行开始),默认为0(指列标行),None表示没有(0为下标开始 展示)
(4)index_col:指定索引列(某一列作为索引列),默认为None(0为下标开始 展示)
(5)usecols:解析指定的列。[int]解析第几列、[str]解析指定列名、lambda函数 解析列名返回为True的列
(6)skiprows=n:跳过头n行后进行读取
try:
#df = pd.read_excel("D:\datasets\score.xls",sheet_name=[0,1],header=0,index_col=None)
#print(df[0])
df = pd.read_excel('D:\datasets\score.xls', 'Sheet1', usecols=[0,1])
print(df)
except ValueError as e:
print("[error] : " + e.__str__())
1.pandas 数据结构 基本属性
(1)df.shape : 返回dataframe的行列维度信息(tuple类型)
(2)df.head(n):预览前n行数据,默认为5
(3)df.tail(n):预览后n行数据,默认为5
(4)df.index:索引名列表
(5)df.columns:列名列表
(6)df.array:用于提取 Index或 Series 里的数据
(7)df.to_numpy():用于提取dataframe里的数据值,转化为numpy的ndarray矩阵
# df.shape : 返回dataframe的行列维度信息(tuple类型)
print(df.shape,type(df.shape))
# df.head(n),预览前n行数据,默认为5
# df.tail(n),预览后n行数据,默认为5
print(df.tail(3))
# df.index:索引名列表
# df.columns:列名列表
print(df.index)
print(df.columns)
# df.array:用于提取 Index或 Series 里的数据
# df.to_numpy():用于提取dataframe里的数据,转化为numpy的ndarray矩阵
#lst = df.index.array
lst = df.to_numpy()
print(type(lst))
2.修改index、columns名的方法
(1)属性赋值法: df.index = [newName] df.columns=[newName]
(2)rename函数:DataFrame.rename(mapper,index,columns,axis=0,inplace=False)
- mapper:将axis维度上的索引,通过字典或者函数修改
- index:将行索引修改,通过字典或者函数。相当于mapper+axis=0
- columns:将列名修改,通过字典或者函数。相当于mapper+axis=1
- axis:指定修改维度,默认为0
- inplace:是否覆盖原数据,默认为False
(3)set_index(keys, drop=True, inplace=False):将某一列设置为行索引
- keys:columns labels
- drop:是否将原列删除
注意:使用有序的index查询数据,会提高数据查询效率!所以尽量使用set_index合理的设置index,优化数据结构
#属性赋值
df.columns = ['a','b','c','d','e']
#rename函数
df.rename(lambda x:x+2,axis=0,inplace=True) #匿名函数修改
df2 = df.rename({0:"一"}) #字典映射修改
df.rename(index=lambda x:x+2,columns={"一":1,"二":2,"三":3,"四":4,"五":5},inplace=True)
#set_index
df.set_index("一",drop=False,inplace=True) #将"一"这列的数值设置为行索引
print(df.index)
3.series字符串处理 series.str
(1)str方法只能在 字符串series(即数值为字符串类型) 上使用,不能在数字列使用
(2)dataFrame没有str属性,只有Series上有
(3)series.str返回一个pandas自己封装的字符串对象,有自己的一套处理方法 Series — pandas 1.3.5 documentation注意:str是series上的属性,字符串方法是str里的与series无关。 str的每个方法都会返回一个新的series对象
df = pd.read_csv(r"D:\datasets\ant-learn-pandas-master\datas\beijing_tianqi\beijing_tianqi_2018.csv")
print(df.head())
print(df["bWendu"].str.len()) #求长度
print(df["bWendu"].str.isnumeric()) #判断是否是数字类型
print(df["bWendu"].str.replace("℃","")) #字符串替换
print(df[df["ymd"].str.startswith("2018-03")]) #筛选2018-03时间的天气数据(startswith返回布尔列表)
# 注意:str是series上的属性,字符串方法是str里的与series无关。 str的每个方法都会返回一个新的series对象
print(df["ymd"].str.replace("-","").str.slice(0,6)) #字符串格式改造+切片
4.正则表达式处理(例子如下)
#1.添加新列,构造初始数据
def get_nuwCol(x):
year,month,day = x["ymd"].split("-")
return f"{year}年{month}月{day}日"
df.loc[:,"中文日期"] = df.apply(get_nuwCol,axis=1)
#2.需求:将 “中文日期”列中的年月日 去掉
#3.方法一:链式处理
df["中文日期"] = df["中文日期"].str.replace("年","").str.replace("月","").str.replace("日","")
print(df)
#4.方法二:正则表达式(str默认开启)
df.loc[:,"中文日期"] = df["中文日期"].str.replace("[年月日]","")
print(df)
(1)切片选择: 利用切片功能选择某些行或某些列,但不支持混合使用(行列混合)
#切片选择:利用切片功能选择某些行或某些列,但不支持混合使用
print(df[['一','二']]) #查询"一",“二”列
print(df[1:3]) #查询1-3行
(2)标签选择(只能通过行列标签选择) :df.loc[索引表达式,列表达式] 支持查询和覆盖修改
# 标签选择(只能通过行列标签选择) df.loc[索引表达式,列表达式] 支持查询和覆盖修改
# (1)单label查询
print(df.loc[1,'二']) #查询单值
print(df.loc[1,['一','五']]) #得到series,可用list()转化
# (2)列表批量查询
print(df.loc[[0,3,4],['一','三','五']])
# (3)区间切片查询(区间全闭)
print(df.loc[0:3,'一':'四'])
# (4)条件表达式查询:原理是将布尔表达式列表传入,返回为True的部分
print(df.loc[df["一"]<=0,:]) #挑选“一”列中<=0的所有数据
print(df.loc[(df["一"]<=0) & (df["四"]>0),:]) # & 且、 | 或、 ~ 非
# (5)函数查询(参数表示某一行或某一列的series)
print(df.loc[lambda df:(df["一"]<=0) & (df["四"]>0),:]) #函数查询 行
print(df.loc[:,lambda df:df.mean()>=5]) #函数查询 列
def my_func(df): #应用传递函数,df为整个dataframe
#print(df)
#每一项一定要加括号!!
return (df.index.astype("int32")>=5) & (df["四"]>=6)
print(df.loc[my_func,:])
(3)位置选择: df.iloc
# 位置选择 df.iloc
print(df.iloc[0:3,0:3]) #与.loc不同的是,这里下标为stop的数据不被选择
df.iloc[0:3,0:3] = 0 #可以直接赋值覆盖
df.iloc[:, lambda df: [0, 1]] #使用函数
(4)取具体值:df.at
# 取具体值
df.at[4,"Q1"]
df.loc[0].at["name"]
(5)分组选择数据: df.groupby
- 分组的理解:按照分组的字段名,将dataFrame中字段值相同的划分为一个子dataFrame,将所有分组封装为一个DataFrameGroupBy对象。
- 总结来说:groupby的过程就是将原有的DataFrame按照groupby的字段,划分为若干个分组DataFrame,被分为多少个组就有多少个分组DataFrame。所以说,在groupby之后的一系列操作(如agg、apply等),均是基于子DataFrame的操作。理解了这点,也就基本摸清了Pandas中groupby操作的主要原理。下面来讲讲groupby之后的常见操作。
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': np.random.randn(8),
'D': np.random.randn(8)})
g = df.groupby("A")
# (1)遍历分组
for name,group in g:
print(name) #打印每个group的name(分组依据为name)
print(group) #打印每个分组的子dataFrame
print()
# (2)分组取值
df_bar = g.get_group('bar')
print(df_bar)
# (3)多字段分组
g = df.groupby(['A','B'])
for name,group in g:
print(name) #打印每个group的name(元组形式)
print(group) #打印每个分组的子dataFrame
print()
df_bar = g.get_group(('foo','one')) #元组取 子dataFrame
print(df_bar)
# (4)分组数据统计
# - 原理:DataFrameGroupBy -〉SeriesGroupby -〉最终作用在每一个子DataFrame或者Series上 -〉 返回一个结果DataFrame或者Series
print(df.groupby("A").mean()) #统计所有数字列的均值,以dataFrame呈现
print(df.groupby("A")['C'].mean()) #统计C列的均值,以Series呈现
# (5)聚合函数 分组数据统计 agg
print(df.groupby('A')['C'].agg(['sum','mean','max'])) #对分组后的C列分别统计sum、mean、max
# - 对分组后的所有列分别统计sum、mean、max
g = df.groupby('A').agg(['sum','mean','max'])
print(g)
print(g[('C','sum')]) 此时columns为 MultiIndex分层索引 元组格式
# - 分别进行数据统计(字典传入)
print(df.groupby('A').agg({'C':'mean','D':'sum'}))
# - 实例:天气数据统计
df = pd.read_csv(r"D:\datasets\ant-learn-pandas-master\datas\beijing_tianqi\beijing_tianqi_2018.csv")
# # 替换掉温度的后缀℃
df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
# # 新增一列为月份
df['month'] = df['ymd'].str[:7]
group_data = df.groupby('month').agg({"bWendu":np.max, "yWendu":np.min, "aqi":np.mean})
# #绘制图像
group_data.plot(kind='bar') #默认为折线图
plt.show()
(6)数据赋值修改 : df[]、df.loc[]、df.iloc[]都可以覆盖修改原数据(要求维度数据格式一致)
(1)列数据直接增加法(无中生有)-- 常用来做计算
# 直接增加法(无中生有)-- 常用来做计算
df.loc[:,"六"] = df["五"] - df["四"]
print(df)
(2)列数据应用apply函数(函数参数为 某行或某列的series)
# apply函数(函数参数为 某行或某列的series)
# -axis=0:纵向 每一列series(行方向) 默认(当然series使用时,不需要指定axis)
# -axis=1:横向 每一行series(列方向)
def get_six(x):
print(x)
if x["五"]==0:
return "happy"
elif x["五"]<0:
return "sad"
return "exceted"
df.loc[:,"六"] = df.apply(get_six,axis=1) #返回series
df.loc[:,"六"] = df.apply(lambda x:"happy" if x["五"]>=0 else "sad",axis=1)
print(df)
(3)列数据条件分组赋值
# 条件分组赋值
df["六"] = '' #广播机制
df.loc[df["四"] + df['五']>=0,"六"] = "happy"
df.loc[df["四"] + df['五']<0,"六"] = "sad"
(4)增加行数据
- 方法一:直接赋值
- 方法二:函数追加 df.append() 可以追加新行
- 方法三:pd.concat 见后方案例
#方法一:直接赋值
df.loc[len(df)+1] = {'Q1':88,'Q2':99} #指定列(字典),无数据列值为NaN
df.loc[101] = ['tom', 'A', 88, 88, 88, 88]
#方法二:函数追加 df.append() 可以追加新行。
df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df.append(df2)
#方法三:pd.concat 见下方
(5)数据删除 drop函数
- 方法:df.drop("A",axis=1,inplace=True) #删除列
(1)数据筛选(判断是否有缺失数据)
df = pd.read_excel("D:\datasets\student_excel.xls",header=0,index_col=None,skiprows=2)
# 数据检测(判断是否有缺失数据)
print(df.isnull()) #返回一个布尔dataFrame (空为True)
print(df["分数"].isnull()) #判断某列的空值
print(df["分数"].notnull()) #不为空为True,常用于筛选非空数据
print(df.loc[df["分数"].notnull(),:]) #筛选分数不为空的所有行数据
(2)空数据删除 df.dropna()
- axis=0 :删除方向,默认为0
- how: 删除方式 'all'方向元素全部缺失则删除;'any'方向元素有一个缺失就删除(默认)
- inplace:是否更新源数据,默认为False
# 空数据删除 df.dropna()
# -axis=0 :删除方向,默认为0
# -how: 删除方式 'all'方向元素全部缺失则删除;'any'方向元素有一个缺失就删除(默认)
# -inplace:是否更新源数据,默认为False
df.dropna(axis=1,how='all',inplace=True) #将全是空值的列删除
df.dropna(axis=0,how='all',inplace=True) #将全是空值的行删除
print(df)
(3)空数据填充 df.fillna()
-value:填充值
-method:填充方式,不能与value共用(ffill-前值填充,bfill-后值填充)
-axis=None:填充维度,一般配合method使用
-inplace:是否覆盖更新源数据
# 空数据填充 df.fillna()
# -value:填充值
# -method:填充方式,不能与value共用(ffill-前值填充,bfill-后值填充)
# -axis=None:填充维度,一般配合method使用
# -inplace:是否覆盖更新源数据
df.fillna(100,inplace=True) #全部填充
df['分数'].fillna(0,inplace=True) #按列填充
df.fillna({"姓名":"匿名","科目":"无","分数":0},inplace=True) #字典填充(不同的列填充不同数据)
df['姓名'].fillna(method="ffill",inplace=True) #姓名前值填充
df.loc[:,"姓名"] = df["姓名"].fillna(method="ffill") #赋值法
df["姓名"] = df["姓名"].fillna(method="ffill")
print(df)
(4)复杂填充:使用每一列的均值填充空值
# 复杂填充:使用每一列的均值填充空值
df = pd.read_excel("D:\datasets\score.xls",sheet_name=1,header=0,index_col=None)
# Series 支持字符串处理方法,可以非常方便地操作数组里的每个元素。这些方法会自动排除缺失值与空值(不处理空值),这也许是其最重要的特性。这些方法通过 Series 的 str 属性访问,一般情况下,这些操作的名称与内置的字符串方法一致。
df.loc[:,"二"] = df.loc[:,"二"].str.replace(".c","").astype("float")
#方法一:同列series填充(行好像不行)
df.fillna(df.mean(),inplace=True)
print(df)
#方法二:字典填充
mean_dict = dict([(col_name,col_avg) for col_name,col_avg in zip(df.columns.tolist(),df.mean().tolist())])
df.fillna(mean_dict,inplace=True)
print(df)
#方法三:遍历填充
for column in list(df.columns[df.isnull().sum() > 0]):
mean_val = df[column].mean()
df[column].fillna(mean_val, inplace=True)
print(df)
(1)df.describe() 展示所有数字列的数据统计特征(返回dataFeame)
# df.describe() 展示所有数字列的数据统计特征(返回dataFeame)
ans = df.describe()
print(ans)
print(ans.loc["max",["一","三"]])
(2)max、mean、min函数统计
# max、mean、min函数统计
print(df["一"].mean()) #统计某一列
print(df["三"].max())
print(df["四"].min())
print(df.mean(axis=0)) #按轴统计(默认为axis=0) 只统计数字部分
print(df.max(axis=0))
print(df.min(axis=0))
(3)value_counts :统计每种类型的数据数量(降序排列) 返回一个series
(4)unique:数据唯一去重(返回ndarry类型)
# value_counts 统计每种类型的数据数量(降序排列) 返回一个series
print(df["五"].value_counts())
# 数据唯一去重(返回ndarry类型)
print(type(df["二"].unique()))
(5)相关系数和协方差(列出数字列之间的协方差和相关系数矩阵)
# 相关系数和协方差(列出数字列之间的协方差和相关系数矩阵)
# 特征工程
print(df.cov()) #协方差矩阵
print(df.corr()) #相关系数矩阵
print(df["一"].corr(df["三"])) #单独查看某两列的相关性
print(df["一"].corr(df["三"] - df["一"])) #单独查看某些运算之间的相关性
(6)数据排序 df.sort_values()
- series :
- ascending=True:True为升序排序,False为降序排序
- inplace=False:是否覆盖更新源数据
- dataFrame:
- by:字符串或list,单列或多列排序
- ascending:bool或list,与by对应
- inplace
- 注意:dataFrame中的series不能使用True来覆盖,各有各的方法
# 数据排序 df.sort_values()
# -series :
# -ascending=True:True为升序排序,False为降序排序
# -inplace=False:是否覆盖更新源数据
# -dataFrame:
# -by:字符串或list,单列或多列排序
# -ascending:bool或list,与by对应
# -inplace
# -注意:dataFrame中的series不能使用True来覆盖,各有各的方法
df = pd.read_excel("D:\datasets\score.xls",sheet_name=1,header=0,index_col=None)
df.sort_values(by="一",ascending=True,inplace=True) #单列排序
df.sort_values(by=["一","三"],ascending=[True,False],inplace=True) #多列排序:先按照'一'排序,相同的按照'三'排序
print(df)
(1)df.to_excel()
- name:写入文件名称。若不存在则会创建,若存在则会覆盖
- sheet_name:表格名称,default ‘Sheet1’
- index=True:是否写入index
- encoding: 编码
# df.to_excel()
# -name:写入文件名称。若不存在则会创建,若存在则会覆盖
# -sheet_name:表格名称,default ‘Sheet1’
# -index=True:是否写入index
# -encoding: 编码
df.to_excel("D:\datasets\score_new.xls",sheet_name="第一",index=False,encoding="utf-8")
(1)数据关联合并 Merge() :多个表格按照字段合并为一个,横向连接
- left、right:要合并的表格
- how='inner':合并类型,'left'、'right'、'outer'、'inner'
- on:合并数据的连接key,两个表都有才行,否则就按照left_on、right_on.
- left_on、right_on:左右表合并数据的对应连接key
- 注意:若未传递on、left_on、right_on,则DataFrame中的所有列的交集将被推断为连接键。
- 合并方式:两表对应的 [连接键],在满足how的规则时,才会把该行连接的数据(所有列整合)放入结果!!
# 一对一数据合并(结果为n条)
left_df = pd.DataFrame({
'sno':[11,12,13,14,15],
'name':['name_a','name_b','name_c','name_d','name_e']
})
right_df = pd.DataFrame({
'sno':[11,12,13,14],
'age':[23,21,22,22]
})
merge_df = pd.merge(left=left_df,right=right_df,on='sno',how='outer')
print(merge_df)
# 一对多数据合并(结果为max(n,m)条)
left_df = pd.DataFrame({
'sno':[11,12,13,14],
'name':['name_a','name_b','name_c','name_d']
})
right_df = pd.DataFrame({
'sno':[11,11,11,12,12,12],
'course':['高等数学','数据结构','大学英语','高等数学','人工智能','大学英语(2)']
})
merge_df = pd.merge(left=left_df,right=right_df,on='sno')
print(merge_df)
# 多对多数据合并(结果为n*m条)
left_df = pd.DataFrame({
'sno':[11,11,12,12,12],
'爱好':['篮球','音乐','篮球','绘画','玩游戏']
})
right_df = pd.DataFrame({
'sno':[11,11,11,12,12,12],
'course':['高等数学','数据结构','大学英语','高等数学','人工智能','大学英语(2)']
})
merge_df = pd.merge(left=left_df,right=right_df,on='sno')
print(merge_df)
(2)表格连接 concat() :任意方向连接表格
- objs:合并的表格列表
- axis=0:合并方向(axis=0为按行上下连接,axis=1为按列左右连接)
- join=outer:合并方式,针对列名层级上的合并(与merge的连接键不同)
- ignore_index=False:是否忽略原索引
注意:若数据不对齐,则会自动填充空值NAN
# (2)表格连接 concat() :任意方向连接表格
# -objs:合并的表格列表
# -axis=0:合并方向(axis=0为按行上下连接,axis=1为按列左右连接)
# -join=outer:合并方式,针对列名层级上的合并(与merge的连接键不同)
# -ignore_index=False:是否忽略原索引
# 注意:若数据不对齐,则会自动填充空值NAN
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3'],
'E': ['E0', 'E1', 'E2', 'E3']
})
df2 = pd.DataFrame({ 'A': ['A4', 'A5', 'A6', 'A7'],
'B': ['B4', 'B5', 'B6', 'B7'],
'C': ['C4', 'C5', 'C6', 'C7'],
'D': ['D4', 'D5', 'D6', 'D7'],
'F': ['F4', 'F5', 'F6', 'F7']
})
con_df = pd.concat([df1,df2],ignore_index=True,join="outer") #上下连接(按照列名),重新排序index,保留所有的列
con_df = pd.concat([df1,df2],ignore_index=True,join="inner") #上下连接,重新排序index,保留共有的列
con_df = pd.concat([df1,df2],axis=1,ignore_index=True) #左右连接,重新排序columns
# 混合连接
s1 = pd.Series(list(range(4)),name="F")
con_df = pd.concat([df1,s1,df2],axis=1)
print(con_df)
(3)pd.append 上下追加行(concat的特殊形式)
# pd.append 上下追加行(concat的特殊形式)
df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
app_df = df.append(df2,ignore_index=True)
print(app_df)
9.pandas axis参数理解
- axis = 0或者 "index":跨行操作,沿着竖直方向向下运动
单行操作,就是指某一行 如(drop、dropna)
聚合操作,指的是跨行聚合(输出列结果) 如(mean、max、min、sum)
- axis = 1或者 "columns":跨列操作,沿着水平方向向右运动
单行操作,就是指某一列 如(drop、dropna)
聚合操作,指的是跨列聚合(输出行结果) 如(mean、max、min、sum)
注意:按哪个axis,就是这个axis要动起来(按这个方向for循环遍历),其他的axis保持不动
df = pd.DataFrame(
np.arange(12).reshape(3,4),
columns = ["A","B","C","D"]
)
# 单行/列操作
df.drop("A",axis=1,inplace=True) #删除列
# 聚合操作
print(df.mean(axis=0)) #向下聚合,输出每一列的结果
print(df.sum(axis=1)) #向右聚合,输出每一行的求和
def get_sum_value(x):
print(x)
return x["A"] + x["B"] +x["C"] + x["D"]
df["sum_value"] = df.apply(get_sum_value,axis=1)
Matplotlib 是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,如 PyQt 和 wxPython。
1.画散点图 scatter(x,y,s,c,marker) 参数说明:
- x、y:散点x、y坐标
- s:散点面积
- c:散点颜色
- marker:散点标记形状(matplotlib.markers图库)
# (1)普通散点图
x = np.random.rand(10)
y = np.random.rand(10)
plt.scatter(x,y)
plt.show()
# (2)更改大小和颜色
# 每个点随机面积。
# - s=float:所有点都是这个大小。
# - s=array :每个点更改为对应大小
s = (30*np.random.rand(10))**2
# 每个点随机颜色。
# - c=rgb字符串('#DC143C'):所有点都为该颜色;颜色字符串('red'):所有点都为该颜色;
# - c=array or list:每个点改为对应颜色
c = np.random.rand(10)
plt.scatter(x,y,s=s,c=c)
plt.scatter(x,y,s=s,c='#DC143C')
plt.show()
# (3)更改形状+多数据绘制+设置图例
x2 = np.random.rand(10)
y2 = np.random.rand(10)
plt.scatter(x,y,marker='o',c='blue',label='circle')
plt.scatter(x2,y2,marker='^',c='#FFD700',label='triangle')
plt.xlabel('x') #x轴说明
plt.ylabel('y') #y轴说明
plt.title('scatter picture') #标题(中文需导入字体)
plt.legend(loc='upper right') #展示每个数据对应的图例(loc参数指定图例位置)
plt.show() #显示图像
2.画线图 plot(x,y,color,linewidth,linestyle,marker)
- x、y:画点x,y坐标
- color:折线颜色
- linewidth:线宽
- linestyle:折线样式
- marker:折线图 点标记样式
x = range(10)
y = np.random.rand(10)
z = np.random.rand(10)
plt.plot(x,y,color='green',linewidth=1.5,linestyle='--',label="line 1",marker='^')
plt.plot(x,z,color='blue',linewidth=1.5,ls='-',label="line 2")
plt.xlim(-0.2,9.2) #调整x轴 显示范围 xlim(left,right)
plt.ylim(-0.2,1) #调整y轴显示范围 ylim(bottom,top)
plt.xticks([0,3,6,9],['zero','three','six','nine']) #x轴 显示刻度 xticks(ticksList[],ticksLabels[])
plt.yticks([0,0.5,1]) #y轴 显示刻度 yticks(ticksList[],ticksLabels[])
# #注意:xticks与xlim有先后设置顺序关系,后设置的会覆盖前面设置的(如果产生冲突)!
plt.xlabel('x')
plt.ylabel('y')
plt.title('mayplotlib line')
plt.legend(loc="best")
plt.grid(linestyle='--') #显示虚线网格
plt.show()
3.画柱状图(条形图) bar(x,height,width,bottom,color,edgecolor,hatch)
- x、height:bars的坐标和高度
- width:bars的宽度,default0.8
- bottom:bars的底部坐标,default0
- color:bars的颜色
- edgeclor:边界颜色
- hatch:填充形状
#(1)简单直方图(水平直方图 使用barh函数)
x = range(10)
y = np.random.rand(10)
plt.bar(x,y,color="blue",edgecolor="black",hatch="/",label="bar")
plt.xticks(x) #显示x轴刻度
plt.xlabel("x")
plt.ylabel("y")
plt.title("bar")
plt.legend()
plt.show()
#(2)并列直方图
size = 5
x = np.arange(size)
a = np.random.random(size)
b = np.random.random(size)
c = np.random.random(size)
# #设置每个刻度总宽度,分类数量
total_width,n = 0.8,3
# #计算每个分类每个刻度下的宽度
width = total_width/n
# #找位置绘图
plt.bar(x,b,color="blue",width=width,label="b")
plt.bar(x-width,a,color="black",width=width,label="a")
plt.bar(x+width,c,color="red",width=width,label="c")
# #柱顶显示数据 text(x,y,strContent,ha)
for i,xx in enumerate(x):
plt.text(xx,b[i]+0.01,"%.2f" % b[i],ha='center',fontsize=10)
plt.text(xx-width,a[i] + 0.01, "%.2f" % a[i], ha='center', fontsize=10)
plt.text(xx+width,c[i] + 0.01, "%.2f" % c[i], ha='center', fontsize=10)
# #设置图例
plt.xlabel("x")
plt.ylabel("y")
plt.title("bars")
plt.legend()
plt.show()
#4.多子图展示
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号
t=np.arange(0.0,2.0,0.1)
s=np.sin(t*np.pi)
# #设置当前画板大小
plt.figure(figsize=(8,8), dpi=80)
plt.figure(1)
# #221 : 前面俩参数指定的是一个画板被分割成的行和列,后面一个参数则指的是当前正在绘制的编号!
ax1 = plt.subplot(221)
ax1.plot(t,s, color="r",linestyle = "--")
ax1.set_title('子图1')
ax2 = plt.subplot(222)
ax2.plot(t,s,color="y",linestyle = "-")
ax2.set_title('子图2')
ax3 = plt.subplot(223)
ax3.plot(t,s,color="g",linestyle = "-.")
ax3.set_title('子图3')
ax4 = plt.subplot(224)
ax4.plot(t,s,color="b",linestyle = ":")
ax4.set_title('子图4')
plt.show()
#5.画3D图
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-4, 4, 0.25)
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y) #生成网格坐标
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R) #网格对应的z
# #绘制图像
# # rstride:行之间的跨度 cstride:列之间的跨度
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='hot')
plt.show()