一. Numpy详解
Numpy的ndarray的属性
Numpy简介
-
NumPy(Numerical Python)是Python数据分析必不可少的第三方库
-
NumPy的出现一定程度上解决了Python运算性能不佳的问题,同时提供了更加精确的数据类型,使其具备了构造复杂数据类型的能力。
-
本身是由C语言开发,是个很基础的扩展,NumPy被Python其它科学计算包作为基础包,因此理解np的数据类型对python数据分析十分重要。
-
NumPy重在数值计算,主要用于多维数组(矩阵)处理的库。用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多
-
重要功能如下
-
高性能科学计算和数据分析的基础包
-
ndarray,多维数组,具有矢量运算能力,快速、节省空间
-
矩阵运算,无需循环,可完成类似Matlab中的矢量运算
-
用于读写磁盘数据的工具以及用于操作内存映射文件的工具
-
Numpy的属性
NumPy的数组类被称作ndarray,通常被称作数组。
ndarray.ndim # 轴
ndarray.shape # 形状, 行列数
ndarray.size #
ndarray.dtype
ndarray.itemsize
数组的维度。这是一个指示数组在每个维度上大小的整数元组。例如一个n排 m列的矩阵,它的shape属性将是(2,3),这个元组的长度显然是秩,即维度或者ndim属性。
-
代码演示
# numpy属性介绍: shape, dtype, ndim, itemsize, size # 导包 import numpy as np # 1. 创建numpy的数组. # arange(15) 等价于python的 range(15), 即: 获取 0 ~ 14的整数 # reshape(3, 5) 把上述数据封装到 3个一维数组中, 每个一维数组的长度为: 5, 然后把三个一维数组封装成1个 二维数组. arr = np.arange(15).reshape(3, 5) # 2. 打印数组, 查看内容 print(arr) # 3. 演示numpy的 属性 print(f'数组的维度: {arr.shape}') # (3, 5) 3个元素(一维数组), 每个元素(一维数组)又有5个元素(值) print(f'数组轴的个数: {arr.ndim}') # 几维数组, 轴就是几, 2 print(f'数组元素类型: {arr.dtype}') # int64 print(f'数组每个元素的占用字节数: {arr.itemsize}') # 8 print(f'数组元素个数: {arr.size}') # 15 print(f'数组类型: {type(arr)}') # <class 'numpy.ndarray'> # 4. 上述的 shape, ndim, size属性 可以 函数写法 实现. # 格式: np.函数名(数组) print(f'数组的维度: {np.shape(arr)}') # (3, 5) 3个元素(一维数组), 每个元素(一维数组)又有5个元素(值) print(f'数组轴的个数: {np.ndim(arr)}') # 几维数组, 轴就是几, 2 print(f'数组元素个数: {np.size(arr)}') # 15 print(f'数组类型: {type(arr)}') # <class 'numpy.ndarray'>
Numpy的ndarray的创建
ndarray介绍
-
NumPy数组是一个多维的数组对象(矩阵),称为ndarray(N-Dimensional Array)
-
具有矢量算术运算能力和复杂的广播能力,并具有执行速度快和节省空间的特点
-
注意:ndarray的下标从0开始,且数组里的所有元素必须是相同类型。
数组形式
import numpy as np a = np.array([2, 3, 4]) print('数组a元素类型: ', a) print('数组a类型:', a.dtype) b = np.array([1.2, 3.5, 5.1]) print('数组b类型:', b.dtype)
zeros() /ones()/empty()
函数zeros创建一个全是0的数组,
函数ones创建一个全1的数组,
函数empty创建一个内容随机并且依赖于内存状态的数组。默认创建的数组类型(dtype)都是float64
zero1 = np.zeros((3, 4)) # 3个一维数组, 每个长度为: 4 print('数组zero1: ', zero1) ones1 = np.ones((2, 3, 4)) # 2个二维数组, 每个二维数组有3个一维数组, 每个一维数组有4个元素1, 整体放入1个数组中 print('数组one1: ', ones1) empty1 = np.empty((2, 3)) print('数组empty1: ', empty1) print(zero1.dtype, ones1.dtype, empty1.dtype)
arange()
类似 python 的 range() ,创建一个一维 ndarray 数组。
np_arange = np.arange(10, 20, 5,dtype=int) # 起始, 结束, 步长, 类型 print("arange创建np_arange:", np_arange) print("arange创建np_arange的元素类型:", np_arange.dtype) print("arange创建np_arange的类型:", type(np_arange))
matrix()
是 ndarray 的子类,只能生成 2 维的矩阵
x1 = np.mat("1 2;3 4") print(x1) x2 = np.matrix("1,2;3,4") print(x2) x3 = np.matrix([[1, 2, 3, 4], [5, 6, 7, 8]]) print(x3)
创建随机数矩阵
import numpy as np # 生成指定维度大小(3行4列)的随机多维浮点型数据(二维), rand固定区间0.0 ~ 1.0 arr = np.random.rand(3, 4) print(arr) print(type(arr)) # 生成指定维度大小(3行4列)的随机多维整型数据(二维), randint()可指定区间(-1, 5) arr = np.random.randint(-1, 5, size=(3, 4)) print(arr) print(type(arr)) #生成指定维度大小(3行4列)的随机多维浮点型数据(二维), uniform()可以指定区间(-1, 5)产生-1到5之间均匀分布的样本值 arr = np.random.uniform(-1, 5, size=(3, 4)) print(arr) print(type(arr)) #生成指定维度大小(3行4列)的随机多维浮点型数据(二维),生成正态分布 arr = np.random.randn(-1, 5, size=(3, 4)) print(arr) print(type(arr))
ndarray的数据类型
# 细节 1. dtype参数,指定数组的数据类型,类型名+位数,如float64, int32 2. astype方法,转换数组的数据类型 # 初始化3行4列数组,数据类型为f1oat64 zeros_float_arr =np.zeros((3,4),dtype=np.float64) print(zeros_float_arr) print(zeros_float_arr.dtype) # float64 # astype转换数据类型,将已有的数组的数据类型转换为int32 zeros_int_arr = zeros_float_arr.astype(np.int32) print(zeros_int_arr) print(zeros_int_arr.dtype) #int32
等比数列
# np.logspace 等比数列, logspace中,开始点和结束点是10的幂 # 我们让开始点为0,结束点为0,元素个数为10,看看输出结果。 a = np.logspace(0,0,10) # 生成10^0 ~ 10^0之间, 10个元素 # 输出结果 a # 假如,我们想要改变基数,不让它以10为底数,我们可以改变base参数,将其设置为2
# 假如,我们想要改变基数,不让它以10为底数,我们可以改变base参数,将其设置为2
等差数列
# np.linspace等差数列 # np.linspace是用于创建一个一维数组,并且是等差数列构成的一维数组,它最常用的有三个参数。 # 第一个例子,用到三个参数,第一个参数表示起始点,第二个参数表示终止点,第三个参数表示数列的个数。
Numpy的内置函数
基本函数
# 基本函数如下 np.ceil(): 向上最接近的整数,参数是 number 或 array np.floor(): 向下最接近的整数,参数是 number 或 array np.rint(): 四舍五入,参数是 number 或 array np.isnan(): 判断元素是否为 NaN(Not a Number),参数是 number 或 array np.multiply(): 元素相乘,参数是 number 或 array np.divide(): 元素相除,参数是 number 或 array np.abs():元素的绝对值,参数是 number 或 array np.where(condition, x, y): 三元运算符,x if condition else y # 注意: 需要注意multiply/divide 如果是两个ndarray进行运算 shape必须一致 # 示例代码 arr = np.random.randn(2, 3) print(arr) print(np.ceil(arr)) print(np.floor(arr)) print(np.rint(arr)) print(np.isnan(arr)) print(np.multiply(arr, arr)) print(np.divide(arr, arr)) print(np.where(arr > 0, 1, -1))
统计函数
np.mean(), np.sum():所有元素的平均值,所有元素的和,参数是 number 或 array np.max(), np.min():所有元素的最大值,所有元素的最小值,参数是 number 或 array np.std(), np.var():所有元素的标准差,所有元素的方差,参数是 number 或 array np.argmax(), np.argmin():最大值的下标索引值,最小值的下标索引值,参数是 number 或 array np.cumsum(), np.cumprod():返回一个一维数组,每个元素都是之前所有元素的 累加和 和 累乘积,参数是 number 或 array # 多维数组默认统计全部维度,axis参数可以按指定轴心统计,值为0则按列统计,值为1则按行统计。 # 实例代码 arr = np.arange(12).reshape(3, 4) print(arr) print(np.cumsum(arr)) # 返回一个一维数组, 每个元素都是之前所有元素的 累加和 print(np.sum(arr)) # 所有元素的和 print(np.sum(arr, axis = 0)) #数组的按列统计和 print(np.sum(arr, axis = 1)) #数组的按行统计和
比较函数
假如我们想要知道矩阵a和矩阵b中所有对应元素是否相等,我们需要使用all方法, 假如我们想要知道矩阵a和矩阵b中对应元素是否有一个相等,我们需要使用any方法。 # np.any(): 至少有一个元素满足指定条件,返回True # np.all(): 所有的元素满足指定条件,返回True # 实例代码 arr = np.random.randn(2, 3) print(arr) print(np.any(arr > 0)) print(np.all(arr > 0))
去重函数
# np.unique():找到唯一值并返回排序结果,类似于Python的set集合 # 实例代码 arr = np.array([[1, 2, 1], [2, 3, 4]]) print(arr) print(np.unique(arr))
排序函数
arr = np.array([1, 2, 34, 5]) print("原数组arr:", arr) # np.sort()函数排序, 返回排序后的副本 sortarr1 = np.sort(arr) print("numpy.sort()函数排序后的数组:", sortarr1) # ndarray直接调用sort, 在原数据上进行修改 arr.sort() print("数组.sort()方法排序:", arr)
Numpy运算
基本运算
# 数组的算数运算是按照元素的。新的数组被创建并且被结果填充。 # 示例代码 import numpy as np a = np.array([20, 30, 40, 50]) b = np.arange(4) c = a - b print("数组a:", a) print("数组b:", b) print("数组运算a-b:", c)
两个ndarray, 一个是arr_a 另一个是arr_b
它们俩之间进行 arr_a + arr_b 或 arr_a - arr_b 或 arr_a * arr_b 这样计算的前提是 shape相同
计算的时候, 位置对应的元素 进行 加减乘除的计算, 计算之后得到的结果的shape 跟arr_a /arr_b 一样
矩阵运算
arr_a.dot(arr_b) 前提
arr_a 列数 = arr_b行数
场景1
import numpy as np a = np.array([[1, 2, 3], [4, 5, 6]]) b = np.array([[1, 2, 3], [4, 5, 6]]) print(a * b) print(np.multiply(a, b))
场景2
import numpy as np x = np.array([[1, 2, 3], [4, 5, 6]]) y = np.array([[6, 23], [-1, 7], [8, 9]]) print(x) print(y) print(x.dot(y)) print(np.dot(x, y))
二. pandas-Series
pandas数据结构
图解
解释
Pandas中只有列 或者 二维表, 没有行的数据结构(
即使是行的数据, 也会通过列的方式展示
).
DataFrame
可以把DataFrame看作由Series对象组成的字典,其中key是列名,值是Series
Series
Series和Python中的列表非常相似,但是它的每个元素的数据类型必须相同
创建Series对象
概述
-
Series也是Pandas中的最基本的数据结构对象,下文中简称s对象;是DataFrame的列对象或者行对象,series本身也具有行索引。
-
Series是一种类似于一维数组的对象,由下面两个部分组成:
-
values:一组数据(numpy.ndarray类型)
-
index:相关的数据行索引标签;如果没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引。
-
创建方式
自动生成索引
import numpy as np import pandas as pd # 创建numpy.ndarray对象 n1 = np.array([1, 2, 3]) print(n1) print(type(n1)) # 创建Series对象 s1 = pd.Series(data=n1) print(s1) print(type(s1)) # 直接创建 s2 = pd.Series(['banana', 42]) print(s2) print(type(s2))
指定索引
s2 = pd.Series(['乔峰','男'], index = ['Name', 'Gender']) print(s)
通过元组和字典创建Series对象
import pandas as pd # 列表 s2 = pd.Series([10, 20, 30]) print('s2: ', s2) print('type(s2): ', type(s2)) # <class 'pandas.core.series.Series'> # 使用元组 tuple1 = (1, 2, 3) s1 = pd.Series(tuple1) print(s1) # 使用字典 字典中的key值是Series对象的索引值,value值是Series对象的数据值 dict1 = {'A': 1, 'B': 2, 'C': 3} s2 = pd.Series(dict1) print(s2)
创建DaraFrame对象
概述
-
DataFrame是一个表格型的==结构化==数据结构,它含有一组或多组有序的列(Series),每列可以是不同的值类型(数值、字符串、布尔值等)。
-
DataFrame是Pandas中的最基本的数据结构对象,简称df;可以认为df就是一个二维数据表,这个表有行有列有索引
-
DataFrame是Pandas中最基本的数据结构,Series的许多属性和方法在DataFrame中也一样适用.
创建方式
字典方式创建
# 定义字典, 记录: 数据 my_dict = { 'id': [1, 2, 3], 'name': ['张三', '李四', '王五'], 'age': [23, 21, 25] } # 将字典 => DataFrame对象 df1 = pd.DataFrame(my_dict) print(df1) print(type(df1)) # <class 'pandas.core.frame.DataFrame'>
列表+元组方式创建
# 定义列表, 记录: 数据 my_list = [ (1, '张三', 23), # 列表内嵌套的(元组或列表)是一行数据 (2, '李四', 1), (3, '王五', 25) ] # 将列表 => DataFrame对象 # columns: 指定列的顺序 # index: 指定索引的值 df3 = pd.DataFrame( data=my_list, columns=['id', 'name', 'age'], index=['x', 'y', 'z'] ) print(df3) print(type(df3)) # <class 'pandas.core.frame.DataFrame'>
index与columns属性
# 定义字典, 记录: 数据 my_dict = { 'id': [1, 2, 3], 'name': ['张三', '李四', '王五'], 'age': [23, 21, 25] } # 将字典 => DataFrame对象 # columns: 指定列的顺序 # index: 指定索引的值 df2 = pd.DataFrame( data=my_dict, columns=['name', 'id', 'age'], index=['x', 'y', 'z'] ) print(df2) print(type(df2)) # <class 'pandas.core.frame.DataFrame'>
Series的常用属性
常用属性
代码演示
读取文件数据
# 1. 读取文件数据, 获取DF对象. df = pd.read_csv('./data/nobel_prizes.csv', index_col='id') # 2. 打印数据的前5条数据. df.head() # 默认获取前5条数据.
loc属性
# 2. 从df对象获取第一行数据, 充当Series对象. # 方式1: 根据 索引列 获取. first_row = df.loc[941] print(first_row) print(type(first_row)) # <class 'pandas.core.series.Series'>
iloc属性
# 方式2: 根据 行号 来获取. first_row = df.iloc[0] print(first_row) print(type(first_row)) # <class 'pandas.core.series.Series'>
其余属性
# 3. 演示Series的属性 print(first_row.shape) # (7,), 维度 print(first_row.size) # 7, 元素个数 print(first_row.dtype) # Series的元素类型, object => 字符串 print(first_row.dtypes) # 效果同上. # 扩展: 演示 int 和 str的 "dtype"属性 print(first_row['year']) # 从Series对象中, 获取: year列的值. print(first_row['year'].dtype) # 从Series对象中, 获取: year列的值 的 数据类型: int64 # print(first_row['category'].dtype) # 从Series对象中, 获取: category列的值 的 数据类型. 报错, 因为字符串没有dtype属性. # index: 获取所有的 索引列(即: 列名) print(first_row.index) print(first_row.keys()) # 效果同上, 即: key()函数 效果 和 index属性效果 有一致. # values: 获取所有的 值 print(first_row.values)
Series的常用方法
常见方法
代码演示
# 1. 创建Series对象. s1 = pd.Series(data=[1, 2, 3, 4, 2, 3], index=['A', 'B', 'C', 'D', 'E', 'F']) print(s1) # 2. 演示Series对象的常用方法. print(len(s1)) # 获取长度, 6 print(s1.head()) # 获取前5条数据 print(s1.head(n=2)) # 获取前2条数据 print(s1.tail()) # 获取后5条数据 print(s1.tail(n=3)) # 获取后3条数据 print(s1.keys()) # 获取所有的列名 print(s1.tolist()) # Series => list列表 print(s1.to_list()) # 效果同上 print(s1.to_frame())# Series => DataFrame对象. print(s1.drop_duplicates()) # 去重, 返回 => Series对象 print(s1.unique()) # 去重, 返回 => list列表 print(s1.sort_values()) # 根据值排序, 默认: 升序, ascending = True print(s1.sort_values(ascending=False)) # 根据值排序, ascending=False => 降序 print(s1.sort_index(ascending=False)) # 根据索引排序 # 平均值, 最大值, 最小值, 求和, 标准差... print(s1.mean()) # 2.5 平均值 print(s1.max()) print(s1.min()) print(s1.sum()) print(s1.count()) # 统计该列的 非空值的个数. print(s1.std()) # 标准差 # 统计每个元素的个数 print(s1.value_counts()) # 类似于SQL语句: select 性别, count(id) from 表名 group by 性别; # 查看Series列的详细信息. print(s1.describe())
案例
# 1. 加载电影数据, 获取df对象. df = pd.read_csv('data/movie.csv') df.head() # 2. 获取所有的列. print(df.columns) # 3. 获取导演的名字 # director = df['director_name'] director = df.director_name # 效果同上 print(director) # 4. 获取主演的 脸书点赞数. actor1_fb = df.actor_1_facebook_likes actor1_fb.head() # 5. 统计不同导演 指导的电影数量, 即: 每个导演名出现了多少次. df.director_name.value_counts() # 6. 查看主演的脸书点赞数, 即: 1000点赞的有几个人, 2000点赞的有几个人... actor1_fb.value_counts() # 7. 打印描述信息. director.describe() # 字符串不是数值, 所以统计信息相对较少. actor1_fb.describe() # 数值的统计信息较多. # 统计(电影总数)全量 print(df.shape) # 统计非空导演总数 df.director_name.count() # 4814
Series的布尔索引
从
scientists.csv
数据集中,列出大于Age
列的平均值的具体值,具体步骤如下:
加载并观察数据集
import pandas as pd df = pd.read_csv('data/scientists.csv') print(df) # print(df.head()) # 输出结果如下 Name Born Died Age Occupation 0 Rosaline Franklin 1920-07-25 1958-04-16 37 Chemist 1 William Gosset 1876-06-13 1937-10-16 61 Statistician 2 Florence Nightingale 1820-05-12 1910-08-13 90 Nurse 3 Marie Curie 1867-11-07 1934-07-04 66 Chemist 4 Rachel Carson 1907-05-27 1964-04-14 56 Biologist 5 John Snow 1813-03-15 1858-06-16 45 Physician 6 Alan Turing 1912-06-23 1954-06-07 41 Computer Scientist 7 Johann Gauss 1777-04-30 1855-02-23 77 Mathematicia # 演示下, 如何通过布尔值获取元素. bool_values = [False, True, True, False, False, False, True, False] df[bool_values] # 输出结果如下 Name Born Died Age Occupation 1 William Gosset 1876-06-13 1937-10-16 61 Statistician 2 Florence Nightingale 1820-05-12 1910-08-13 90 Nurse 6 Alan Turing 1912-06-23 1954-06-07 41 Computer Scientist
计算Age
列的平均值
# 获取一列数据 df[列名] ages = df['Age'] print(ages) print(type(ages)) print(ages.mean()) # 输出结果如下 0 37 1 61 2 90 3 66 4 56 5 45 6 41 7 77 Name: Age, dtype: int64 <class 'pandas.core.series.Series'> 59.125
输出大于Age
列的平均值的具体值
print(ages[ages > ages.mean()]) # 输出结果如下 1 61 2 90 3 66 7 77 Name: Age, dtype: int64
总结
# 上述代码优化版, 一行搞定. # 补充: df['列名'] 和 df.列名 都可以从df中获取到指定的 列. print(df.Age[df.Age > df.Age.mean()]) print(df['Age'][df['Age'] > df['Age'].mean()])
Series的运算
Series和数值型变量计算时,变量会与Series中的每个元素逐一进行计算;
两个Series之间计算时,索引值相同的元素之间会进行计算;索引值不同的元素的计算结果会用NaN值(缺失值)填充。
Series和数值型变量计算
# 加法 print(ages + 10) # 乘法 print(ages * 2) # 输出结果如下 0 47 1 71 2 100 3 76 4 66 5 55 6 51 7 87 Name: Age, dtype: int64 0 74 1 122 2 180 3 132 4 112 5 90 6 82 7 154 Name: Age, dtype: int64
两个Series之间计算
索引值相同的元素之间会进行计算;索引值不同的元素的计算结果会用NaN值(缺失值)填充
print(ages + ages) ==> ages.sort_index(ascending=False) + ages print('=' * 20) print(pd.Series([1, 100])) print('=' * 20) print(ages + pd.Series([1, 100])) # 输出结果如下 0 74 1 122 2 180 3 132 4 112 5 90 6 82 7 154 Name: Age, dtype: int64 ==================== 0 1 1 100 dtype: int64 ==================== 0 38.0 1 161.0 2 NaN 3 NaN 4 NaN 5 NaN 6 NaN 7 NaN dtype: float64