Numpy和Pandas的简单使用
Numpy
Numpy基本数据结构
-
np.array()
函数接受一个多维list,返回对应纬度的矩阵vector = np.array([1, 2, 3, 4]) matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
-
特殊矩阵:
np.zeros((第一维size, 第二维size, ...))
初始化全零矩阵,要求传入的是一个元组,存储各个维度上的尺寸.np.ones((第一维size, 第二维size, ...))
初始化全一矩阵,要求传入的是一个元组,存储各个维度上的尺寸.np.arange(起点, 终点, 步长)
创建一个序列np.eye(size)
创建一个size
*size
的单位矩阵np.linspace(起点, 终点, 数列长度)
返回一个从起点
到终点
线性插值的长度为数列长度
序列np.logspace(起点指数, 终点指数, 数列长度, base=底数)
返回从 底数起点指数 到底数终点指数的长度为数列长度
的等比序列
Numpy基本操作和属性
-
一个矩阵中存储的数据类型应该相同,其
dtype
属性返回矩阵中元素的数据类型
使用astype(类型)
方法安全地改变元素的数据类型.vector = numpy.array(["1", "2", "3", "4"]) # ['1' '2' '3' '4'] vector = vector.astype(float) # [1. 2. 3. 4.]
-
矩阵对象的
shape
属性返回矩阵的形状,即其各维度上的尺寸.-
使用
reshape(new_shape)
方法更改重整原矩阵的形状,若传入某个维度上尺寸的为-1
,则根据其他维度的尺寸反推此维度的尺寸.matrix = np.arange(6).reshape(-1, 3) # 得到 [[0 1 2] [3 4 5]]
-
使用
resize(new_shape)
方法返回一个新矩阵.matrix = np.arange(6).resize(-1, 3) # 得到 [[0 1 2] [3 4 5]]
值得注意的是,
reshape()
方法在原矩阵上进行修改;resize()
方法不修改原矩阵,而是返回一个新矩阵.-
使用
ravel()
方法将高维矩阵拉伸成一维向量matrix = np.arange(6).reshape(-1, 3) matrix = matrix.ravel() # 得到 [0 1 2 3 4 5]
-
-
Numpy矩阵支持下标索引与切片,与python的
list
类似matrix = numpy.array([[5,10,15], [20,25,30], [35,40,45]]) matrix[:,1] # 得到[10 25 40] matrix[:,0:2] # 得到[[5 10] [20 25] [35 40]] matrix[1:3,:2] # 得到 [[20 25] [35 40]]
Numpy矩阵的
reshape()
和切片
并不返回新矩阵,只是更改了原矩阵的一个视图(view
),对新视图进行的修改也会作用在原视图上(这与Python原生列表的切片是不同的).可以使用对象的copy()
方法进行深拷贝,从而避免在原对象上进行修改. -
Numpy矩阵支持比较运算符, 返回一个与原矩阵尺寸相同的bool矩阵,存储对对应为进行判断的结果
print(matrix == 10) # 得到 [[False True False] [False False False] [False False False]] print(matrix > 10) # 得到 [[False False True] [ True True True] [ True True True]]
与MATLAB类似,可以用矩阵比较运算的结果来索引矩阵
matrix[matrix>10]=10 # 得到 [[ 5 10 10] [10 10 10] [10 10 10]]
-
求最值和求和
-
使用
min(axis=维度)
,max(axis=维度)
,sum(axis=维度)
分别返回数组在某维度
上的最小值,最大值和求和matrix = np.arange(9).reshape((3, 3)) matrix.min(axis=1) # array([0, 3, 6]) matrix.max(axis=1) # array([2, 5, 8]) matrix.sum(axis=1) # array([3, 12, 21])
值得注意的是,
min()
,max()
,sum()
方法会对原矩阵进行降维(例如上面例子中将原本的二维矩阵变为一维向量),这可能会引起bug.
若要保持矩阵原本的形状不变,只需将keepdims
参数设为True
即可. -
使用
argmin(axis=维度)
,argmax(axis=维度)
可以得到最值在原矩阵中对应的索引.
-
-
排序
numpy.sort(矩阵, axis=维度)
返回对矩阵
对应维度
进行排序后的矩阵,注意返回的是一个新矩阵,而原矩阵不改变numpy.argsort(矩阵, axis=维度)
返回排序后矩阵每个位置的元素在原矩阵中对应的索引.
Numpy矩阵运算
-
加减法:
-
相同维度矩阵加减,对应位置元素相加减
a1 = np.array([20,30,40,50]) # 得到 [20 30 40 50] a2 = np.arange(4) # 得到 [0 1 2 3] a3 = a1 - a2 # 得到 [20 29 38 47]
-
矩阵加减某个标量,则对每个元素都加减这个标量
a1 = np.array([20,30,40,50]) # 得到 [20 30 40 50] a2 = a1-1 # 得到 [19 29 39 49]
-
-
矩阵乘法:
- 相同维度矩阵使用
*
运算符,返回尺寸相同的新矩阵,其存储的是对应位置元素相乘结果 - 使用
矩阵1.dot(矩阵2)
或np.dot(矩阵1,矩阵2)
计算矩阵点乘
A = np.array([[1,1],[0,1]]) B = np.array([[2,0],[3,4]]) # 矩阵对应位置相乘 print(A*B) # 得到 [[2 0] [0 4]] # 矩阵点乘两种写法 print(A.dot(B)) # 得到 [[5 4] [3 4]] print(np.dot(A,B)) # 得到 [[5 4] [3 4]]
- 相同维度矩阵使用
-
乘方操作: 对矩阵每个元素进行乘方操作
A = np.arange(5) A = A ** 2 # 得到 [0 1 4 9 25]
-
矩阵拼接:
-
使用
tile(矩阵,(第一维倍数, 第二维倍数, ...))
方法将矩阵对应尺寸上延展对应倍数matrix = np.arange(2) matrix = np.tile(matrix,(1,3)) # 得到 [[0 1 0 1 0 1]] matrix = np.tile(matrix,(3,1)) # 得到 [[0 1] [0 1] [0 1]]
-
使用
vstack([被拼接的矩阵列表])
和hstack([被拼接的矩阵列表])
可以将对应方向上维度相同的矩阵横向或纵向拼接a = np.array([1, 2, 3]) b = np.array([2, 3, 4]) np.vstack((a,b)) # 得到 array([[1, 2, 3], [2, 3, 4]])
a = np.array([[1],[2],[3]]) b = np.array([[2],[3],[4]]) np.hstack((a,b)) # 得到 array([[1, 2], [2, 3], [3, 4]])
-
-
矩阵的转置,行列式,求逆
使用.T
属性求矩阵的转置
使用np.linalg.inv(矩阵)
求矩阵的逆
使用np.linalg.det(矩阵)
求矩阵的行列式matrix = np.arange(1,5).reshape(2,2) # 求矩阵转置 print(matrix.T) # 得到 [[1 3] [2 4]] # 求矩阵的逆 print(np.linalg.inv(matrix)) # 得到 [[-2. 1. ] [ 1.5 -0.5]] # 求矩阵的行列式 print(np.linalg.det(matrix)) # 得到 -2.0000000000000004
Pandas
pandas数据读取
使用pandas的read_csv()
方法读取csv数据,读取到的数据将会被包装成一个DataFrame
对象.
food_info = pd.read_csv("food_info.csv")
type(food_info) # pandas.core.frame.DataFrame
food_info.dtypes # DataFrame中包含的每个对象都被看成Numpy对象
food_info.columns.tolist() # 得到所有列名
food_info.values.tolist() # 以np.array形式返回其内容
pandas数据展示
-
调用
DataFrame
对象的head(行数)
方法显示前行数
行,tail(行数)
方法显示前head
行.food_info.head() # 显示前5行 food_info.head(3) # 显示前3行 food_info.tail() # 显示后5行
-
调用
DataFrame
对象的shape()
方法返回其矩阵形状food_info.shape # (8618, 36)
-
调用
DataFrame
对象的loc[行数]
属性取第行数
行,行数
可以是一个int数或一个列表- 若
行数
为一个int数字,则返回一个Series
对象 - 若
行数
为一个列表,则返回一个DataFrame
对象
type(food_info.loc[[0]]) # pandas.core.frame.DataFrame type(food_info.loc[0]) # pandas.core.series.Series
food_info.loc[3:5] food_info.loc[[2,5,10]]
- 若
-
对
DataFrame
对象使用下标索引可以返回某几列- 若传入一个索引值,则返回一个
Series
对象 - 若传入一个索引列表,则返回一个
DataFrame
对象
ndb_col = food_info["NDB_No"] zinc_copper_col = food_info[["Zinc_(mg)", "Copper_(mg)"]] type(ndb_col) # pandas.core.series.Series type(zinc_copper_col) # pandas.core.frame.DataFrame
- 若传入一个索引值,则返回一个
Pandas数据处理
-
对
DataFrame
对象进行加减乘除,等价于对其每一个元素进行加减乘除div_100 = food_info["Iron_(mg)"] / 100 add_100 = food_info["Iron_(mg)"] + 100 sub_100 = food_info["Iron_(mg)"] - 100 mult_100 = food_info["Iron_(mg)"] * 100
例子: 计算加权指标
# Score = 2*(protein_(g))-0.75*(Lipid_Tot_(g)) weighted_protein = food_info["Protein_(g)"] * 2 weighted_fat = -0.75 * food_info["Lipid_Tot_(g)"] initial_rating = weighted_protein + weighted_fat
-
取最值,平均值:
max()
,min()
,mean()
,Pandas会自动剔除不存在的坏值# 使用max()取最大值 max_calories = food_info["Energ_Kcal"].max() mean_calories = food_info["Energ_Kcal"].mean()
例子: 归一化数据并将其作为新行
normalized_protein = food_info["Protein_(g)"] / food_info["Protein_(g)"].max() normalized_fat = food_info["Lipid_Tot_(g)"] / food_info["Lipid_Tot_(g)"].max() food_info["Normalized_Protein"] = normalized_protein food_info["Normalized_Fat"] = normalized_fat
-
排序
sort_value()
方法将所有行按值排序
sort_index()
方法将所有行按索引排序# 第一个参数: 排序的键 # inplace: 是否直接替换原对象 # ascending: 升序与否 food_info.sort_values("Sodium_(mg)", inplace=True) food_info.sort_values("Sodium_(mg)", inplace=True, ascending=False)
-
数据透视表
titanic_surival = pd.read_csv("titanic_train.csv")
使用
pivot_table()
函数生成数据透视表,其参数如下index
:指定以哪个指标为基准进行统计values
:统计的字段,可以为索引,也可以为索引列表aggfunc
:对统计字段的值应用的方法,默认取平均值,即np.mean()
# 统计不同船舱的获救概率 passenger_survival = titanic_surival.pivot_table(index="Pclass", values="Survived", aggfunc=np.mean) # 统计不同船舱的年龄 passenger_age = titanic_surival.pivot_table(index="Pclass", values="Survived") # 统计每个港口的 总票价 和 总获救人数 port_stats = titanic_surival.pivot_table(index="Embarked", values=["Fare", "Survived"], aggfunc=np.sum)
-
删除空值
使用dropna()
来删除带有空值的行或列,其参数列表如下axis
:维度,取0
删除有空值的列,取1
删除有空值的行subset
:删除掉subset
字段有空值的行
# 删除掉所有有空值的列, axis=1 drop_na_columns = titanic_surival.dropna(axis=1) # 删除掉所有["Age"或"Sex"字段]有空值的行 new_titanic_survival = titanic_surival.dropna(axis=0, subset=["Age", "Sex"])
-
重新建立索引
使用reset_index
方法来重新建立索引new_titanic_survival = titanic_surival.sort_values("Age", ascending=False) # 将数据集按照当前顺序重新建立索引,drop代表放弃原来索引 titanic_reindexed = new_titanic_survival.reset_index(drop=True)
-
DataFrame
对象的apply(函数)
方法可以对数据每一列都执行自定义函数,并将结果汇总到一个Series
对象中.# 返回每一列的第100名 def hundredth_row(column): # Extract the hundredth item hundredth_item = column.loc[99] return hundredth_item # 对每个字段返回其第100位,下一行等价于 titanic_surival.loc[99] hundredth_row = titanic_surival.apply(hundredth_row)
# 统计每一列的空值个数 def not_null_count(column): column_null = pd.isnull(column) null = column[column_null] return len(null) # 对每个字段返回其空值个数 column_null_count = titanic_surival.apply(not_null_count)
# 对每一行的Pclass字段编码 def which_class(row): pclass = row["Pclass"] if pd.isnull(pclass): return "Unknown" elif pclass == 1: return "First Class" elif pclass == 2: return "Second Class" elif pclass == 3: return "Third Class" # 返回每一行的Pclass字段的编码 classes = titanic_surival.apply(which_class, axis=1)
Pandas的基本数据结构:DataFrame
和Series
DataFrame
和Series
为Pandas最重要的两种结构,其中Series
类似于一维向量,而DataFrame
类似于二维矩阵.
Series
可以看作是Numpy对象的集合,DataFrame
可以看作是Series
的集合
fandango = pd.read_csv('fandango_score_comparison.csv')
# 对DataFrame进行索引取值得到Series
series_film = fandango['FILM']
type(series_film) # pandas.core.series.Series
可以使用Series()
构造函数生成Series
对象,index
参数指定索引
from pandas import Series
film_names = fandango['FILM'].values # 得到所有电影名字
rt_scores = series_rt.values # 得到所有评分值
# 以电影名字为索引,将电影评分构成一个Series
series_custom = Series(rt_scores, index=film_names)
# 这样可以以电影名为索引找到电影
series_custom[['Minions (2015)', 'Leviathan (2014)']]
series
的底层实现用的是np.ndarray
,因此series
对象可以替代ndarray
作为函数参数
np.add(series_custom, series_custom)
np.sin(series_custom)
np.max(series_custom)