文章目录
- Numpy 部分
- NumPy的数组类被称作ndarray,通常被称作数组。
- 属性
- 创建方法
- 内置函数
- 运算
- 基本运算
- 矩阵运算
- Pandas部分
- 总述
- Serise 对象
- 创建
- 属性
- 方法
- 运算
- DataFrame
- 属性
- 索引操作
- 添加删除插入列
- 保存读取文件
- 保存
- 读取
- 数据加载
- 分组聚合
- 语法格式:
- 基本绘图
- 数据组合和缺失值处理
- 数据组合
- Dataframe 数据组合 concat连接
- df对象和df对象拼接
- df对象和series对象拼接
- DataFrame 数据组合 添加 行和列
- 添加行
- 添加列
- 一对一合并
- join 方式
- 缺失值
- 加载缺失值
- 缺失值可视化
- 缺失值处理和非时序数据缺失值填充
- 删除缺失值
- 非时序数据填充
- 时序数据填充
- series 中的apply方法
- DataFrame 中的apply方法
- 向量化函数
- 分组聚合
- 分组转换
- 分组过滤
- DataFrameGroupby对象
- 日期类型处理
- Pandas日期时间类型简介
- 日期时间类型相关操作
- 生成规则如下:
- Matplotlib 数据可视化
- Matplotlib的API介绍
Numpy 部分
NumPy的数组类被称作ndarray,通常被称作数组。
属性
ndim 维度(几轴)
shape 形状
dtype 数据类型
size 大小(元素个数)
type 数组类型
创建方法
zeros() 创建一个全是0的数组
ones() 创建一个全是1的数组
empty() 创建一个内容随机并依赖于内存状态的数组
arange() 创建一个一维的ndarray数组
matrix() 生成一个二维矩阵
logspace(参1,参2,参3) 等比数列 参1 : 起始点 参2: 结束点 参3: 步长
linspace(参1,参2,参3) 等差数列 参1 : 起始点 参2: 结束点 参3: 步长
内置函数
- 基本函数
ceil() 天花板数 向上取整
floor() 地板数 向下取整
rint() 四舍五入
isnan() 判断是否为空(NAN)
multiply() 元素相乘
divide() 元素相除
abs() 绝对值
where(condition , x, y) 三元运算符 x if condition else y
- 统计函数
mean() 平均值
sum() 和
max() 最大值
min() 最小值
std() 标准差
var() 方差
argmax() argmin() 最大值 最小值 的下标索引值
cumsum() 累加和
cumprod() 累乘积
- 比较函数
any() 一个元素满足 返回True
all() 所有元素满足 返回 True
- 去重函数
unique() 找到唯一值并返回排序结果
- 排序函数
sort()
np.sort() 返回排序后的副本
ndarray对象.sort() 直接对 ndarray对象排序
运算
基本运算
两个ndarray, 一个是arr_a 另一个是arr_b
它们俩之间进行 arr_a + arr_b 或 arr_a - arr_b 或 arr_a * arr_b 这样计算的前提是 shape相同
计算的时候, 位置对应的元素 进行 加减乘除的计算, 计算之后得到的结果的shape 跟arr_a /arr_b 一样
数组a [20 30 40 50]
数组b [0 1 2 3]
a-b [20 29 38 49]
矩阵运算
前提是 a的行数 = b的列数 b的行数 = a的列数
a的第几行 * b 的第几列 元素相加 填入对应的结果集中
Pandas部分
总述
pandas存储时没有行只有列 每列为一个Series对象 多个Series对象组成一个DataFrame
- DataFrame 可以看作由Series 对象 组成的字典 key是列名 值是Series
- Serise 与 列表非常相似 存储一列信息
Serise 对象
创建
创建方式 pandas.Series(值,参数)
指定索引 参数 index = [值1,值2]
值可以是字典/ndarray/列表/元组等
属性
loc 使用索引值取子集
iloc 使用索引位置取自己
dtype series内容的类型
T 转置矩阵
shape 维度
size 元素数量
values 值
index 索引值
方法
append 连接两个或多个series
corr 计算与另一个series 的相关系数
cov 计算与另一个series 的协方差
describe 计算常见统计量
drop_duplicates 返回去重后的series
equals 判断两个series 是否相同
get_values 获取series 的值 作用与values 属性相同
hist 直方图
isin 判断是否包涵某些值
min max 最小值 最大值
mean 算数平均值
median 中位数
mode 众数
quantile 返回指定位置的分位数
replace 用指定值代替series中的值
sample 返回随机采样值
sort_values 对值进行排序
to_frame series转化为dataframe
unique 去重返回数组
value_counts 统计不同值数量
keys 获取索引值
head tail 查看前五个 后五个值
运算
series 计算时 变量会和series中的每个元素逐一计算
两个series 之间计算时 索引值相同的互相计算 不同的位置返回nan
DataFrame
可以通过字典 / 列表+ 元组等方式创建
属性
shape 维度
size 元素个数
values 数据值
ndim 维度数
dtypes 元素类型
index 索引值
columns 列名对象
head tail 前 后 五行数据
info 基本信息
describe 描述信息
len 行数
min max 最小最大
count 非空值个数
mean 平均值
索引操作
set_index() 设置索引列
reset_index() 重置索引列
rename() 修改行索引 列索引名 参数 index 行索引 columns 列索引
添加删除插入列
df[列名] = 值 可以给df对象新增一列, 默认: 在df对象的最后添加一列.\
drop(名称 , axis = 行/列) 删除一行或列 根据 axis 参数 删 rows 0 行 columns 1 列
也可以drop([行索引1,行索引2]) 按行索引删除
insert() 表示插入列. 参数解释: loc:插入位置(从索引0开始计数), column=列名, value=值
保存读取文件
保存
to_pickle('路径名') 保存为 pickle文件
to_csv('路径名') 保存为csv文件
to_excel('路径名') 保存为 excel文件
pandas 读写excel需要额外安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xlwt
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openpyxl
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xlrd
读取
read_pickle('路径名') 读取 pickle文件
read_csv('路径名') 读取csv文件
read_excel('路径名') 读取 excel文件
数据加载
df对象[['列名1', '列名2', '列名3'...]] 按列加载数据
df对象.loc[[行索引],[列名]] 按行加载数据
df对象.loc[:,[列名]] 获取所有行的某些列
df对象.loc[:,3:5] 获取列编号为 3 ~ 5 区间的数据, 包左不包右, 即: 只获取索引为3, 4列的数据.
loc只接收 行列名, iloc只接收行列序号, 搞反了, 会报错.
分组聚合
先将数据分组 对每组的数据再去进行统计计算如,求平均,求每组数据条目数(频数)等 再将每一组计算的结果合并起来,可以使用DataFrame的groupby方法完成分组/聚合计算
语法格式:
df.groupby('分组字段')['要聚合的字段'].聚合函数()
df.groupby(['分组字段','分组字段2'])[['要聚合的字段','要聚合的字段2']].聚合函数()
基本绘图
df对象.plot()
line 折线图 bar 柱状图 pie 饼图
数据组合和缺失值处理
数据组合
Dataframe 数据组合 concat连接
概述: 连接是指把某行或某列追加到数据中, 数据被分成了多份可以使用连接把数据拼接起来
把计算的结果追加到现有数据集,也可以使用连接
df对象和df对象拼接
行拼接参考: 列名, 列拼接参考: 行号
格式 pandas.concat([df对象1,df对象2,df对象3], axis = 拼接方式)
拼接方式 rows 0 行拼接 columns 1 列拼接
df对象和series对象拼接
由于Series是列数据(没有行索引), concat()默认是添加行, 所以 它们拼接会新增一列. 缺值用NaN填充
DataFrame 数据组合 添加 行和列
添加行
通过 concat 和 append 都可实现添加一行
df5 = pd.DataFrame([['n1', 'n2', 'n3', 'n4']], columns=['A', 'B', 'C', 'D'])
pd.concat([df1, df5])
df1.append(df5)
添加列
方式1: 通过 df[列名] = [列值1, 列值2...] 的方式, 可以给 df添加列.
方式2: 通过 df[列名] = Series对象 的方式, 添加1列. # 值的个数和列的个数, 匹不匹配均可.
DataFrame 数据组合 merge 方式
概述 : 在使用concat连接数据时,涉及到了参数**join(join = ‘inner’,join = ‘outer’)
数据库中可以依据共有数据把两个或者多个数据表组合起来,即join操作
DataFrame 也可以实现类似数据库的join操作
Pandas可以通过pd.join命令组合数据,也可以通过pd.merge命令组合数据
merge更灵活,如果想依据行索引来合并DataFrame可以考虑使用join函数
一对一合并
df对象.merge(df对象子集的 id1,id2, id3) on表示关联字段, how表示连接方式
how 关联方式 有
left 左外连接
right 右外连接
inner 内连接
outer 外连接
-
on 连接的字段, 如果左右两张表 连接的字段名字相同直接使用 on=‘关联字段名’
-
如果名字不同, left_on 写左表字段, right_on 写右表字段.
-
连接之后, 两张表中如果有相同名字的字段, 默认会加上后缀 默认值 _x, y
suffixes:(" x", “_ y”)
join 方式
- 使用join合并,可以是依据两个DataFrame的行索引,
- 或者一个DataFrame的行索引另一个DataFrame的列索引进行数据合并
如果合并的两个数据有相同的列名,需要通过lsuffix,和rsuffix,指定合并后的列名的后缀
例:
stocks_2016.join(stocks_2017, lsuffix='_2016', rsuffix='_2017', how='outer') # 默认是: 左外连接.
缺失值
简介
- 好多数据集都含缺失数据。缺失数据有多重表现形式
- 数据库中,缺失数据表示为NULL
- 在某些编程语言中用NA表示
- 缺失值也可能是空字符串(’’)或数值
- 在Pandas中使用NaN表示缺失值
- Pandas中的NaN值来自NumPy库,NumPy中缺失值有几种表示形式:
- NaN,NAN,nan,他们都一样
- 缺失值和其它类型的数据不同,它毫无意义,NaN不等于0,也不等于空串
- 数据中出现缺失值是很常见的
- 计算的过程中, 两个表join 可能会有缺失
- 原始的数据中也有可能直接带着缺失值
- 数据处理和模型训练的时候, 有很多场景要求必须先把缺失值处理掉,
- 想处理缺失值先要在数据中找到缺失值
# 1. 缺失值不是 True, False, 空字符串, 0等, 它"毫无意义"
print(np.NaN == False)
print(np.NaN == True)
print(np.NaN == 0)
print(np.NaN == '')
# 2. np.nan np.NAN np.NaN 都是缺失值, 这个类型比较特殊, 不同通过 == 方式判断, 只能通过API
print(np.NaN == np.nan)
print(np.NaN == np.NAN)
print(np.nan == np.NAN)
# 3. Pandas 提供了 isnull() / isna()方法, 用于测试某个值是否为缺失值
import pandas as pd
print(pd.isnull(np.NaN)) # True
print(pd.isnull(np.nan)) # True
print(pd.isnull(np.NAN)) # True
print(pd.isna(np.NaN)) # True
print(pd.isna(np.nan)) # True
print(pd.isna(np.NAN)) # True
# isnull() / isna()方法 还可以判断数据.
print(pd.isnull(20)) # False
print(pd.isnull('abc')) # False
# 4. Pandas的notnull() / notna() 方法可以用于判断某个值是否为缺失值
print(pd.notnull(np.NaN)) # False
print(pd.notnull('abc')) # True
加载缺失值
在加载数据时
可以通过 keep_default_na 参数 设置 加载数据时候是否加载缺失值
可以通过 na_values=[值1, 值2...] 加载数据时, 设定哪些值为缺失值.
缺失值可视化
# 导包
import missingno as msno
柱状图 展示缺失值的个数
msno.bar(数据对象名)
缺失值处理和非时序数据缺失值填充
删除缺失值
dropna() 函数 参数介绍
subset=None 默认是: 删除有缺失值的行, 可以通过这个参数来指定, 哪些列有缺失值才会被删除
例如: subset = ['Age'] 只有当年龄有缺失才会被删除
inplace=False 通用参数, 是否修改原始数据默认False
axis=0 通用参数 按行按列删除 默认行
how='any' 只要有缺失就会删除 还可以传入'all' 全部都是缺失值才会被删除
非时序数据填充
用 0 来填充 空值.
数据对象名.fillna(0)
用平均数, 来替换 某列的空值.
数据对象名[列名].fillna(数据对象名[列名].mean())
时序数据填充
加载数据时
可以通过 设置 prase_dates 把某些列转成时间列
index_col 设置指定列为索引列
填充方式 1 固定值填充
数据对象名.dillna(填充数据)
2. ffill 填充 用时间序列空值的上一个非空值填充
数据对象名.fillna(method = 'ffill')
3. bfill 填充 用时间序列空值的下一个非空值填充
数据对象名.fillna(method = 'bfill')
4. 线性插值方法填充缺失值
数据对象名.interpolate(limit_direction = 'both')
缺失值处理的套路
- 能不删就不删 , 如果某列数据, 有大量的缺失值(50% 以上是缺失值, 具体情况具体分析)
- 如果是类别型的, 可以考虑使用 ‘缺失’ 来进行填充
- 如果是数值型 可以用一些统计量 (均值/中位数/众数) 或者业务的默认值来填充
series 中的apply方法
apply函数可以接收一个自定义函数, 可以将DataFrame的行/列数据传递给自定义函数处理
import pandas as pd
# 1. 准备数据
df = pd.DataFrame({'a': [10, 20, 30], 'b': [20, 30, 40]})
df
# 2. 创建1个自定义函数.
def my_func(x):
# 求平方
return x ** 2
def my_func2(x, e):
# 求x的e次方
return x ** e
# 3. apply方法有一个func参数, 把传入的函数应用于Series的每个元素
# 注意, 把 my_func 传递给apply的时候,不要加上小括号.
df['a'].apply(my_func) # 传入函数对象.
df['a'].apply(my_func2, e = 2) # 传入函数对象, e次幂(这里是平方)
df['a'].apply(my_func2, e = 3) # 传入函数对象, e次幂(这里是立方)
DataFrame 中的apply方法
格式
df.apply(func,axis = )
axis = 0 按列传递数据 传入一列数据(Series)
axis = 1 按行传递数据 传入一列数据(Series)
代码演示
# 1. 把上面创建的 my_func, 直接应用到整个DataFrame中
df.apply(my_func) # my_func函数会作用到 df对象的每一个值.
# 2. 报错, df对象是直接传入一列数据的, 并不是 一个值一个值传入的
def avg_3(x, y, z):
return (x + y + z) / 3
df.apply(avg_3)
# 3. 演示 df对象, 到底传入啥.
def my_func3(x):
print(x)
print(f'x的数据类型是: {type(x)}')
# 每次传入 1 列
# df.apply(my_func3, axis=0) # 0(默认): 列, 1: 行
# 每次传入 1 行
df.apply(my_func3, axis=1) # 0(默认): 列, 1: 行
向量化函数
-
分析代码
def avg_test2(x,y): if x==20: return np.NaN else: return (x+y)/2 avg_test2(df['a'],df['b'])
-
报错原因
- 上面的方法调用之所以报错, 就是因为if 需要传入的是 一个True/False .
- 但是我们传入的是一个 True/False 组成的Series 此时if 不能做出判断, 抛出了错误
- 想让上面的代码正常的执行, 我们需要把 Series里的每一个值遍历的传递给if 做多次判断,
- 此时必须要自己写for循环, 可以通过 np.vectorize(avg_test2) 这种方式,
- 把这个方法变成一个向量化的方法(会遍历每一个值(分量)多次调用这个方法)
格式
@ np.vectorize
或者
np.vectorize(函数名)
Lambda 表达式
-
背景
- 当函数比较简单的时候, 没有必要创建一个def 一个函数, 可以使用lambda表达式创建匿名函数
-
格式
lambda 形参列表 : 函数体
-
代码演示
df.apply(lambda x: x + 1) df.apply(lambda x: x.isnull().sum()) df.apply(lambda x: x.mean())
分组聚合
概述
- 在SQL中我们经常使用 GROUP BY 将某个字段,按不同的取值进行分组,
- 在pandas中也有groupby函数, 分组之后,每组都会有至少1条数据, 将这些数据进一步处理,
- 返回单个值的过程就是聚合,比如分组之后计算算术平均值, 或者分组之后计算频数,都属于聚合
例如
df.groupby('year').lifeExp.mean()
df[df['year'] == 1952]['lifeExp'].mean()
df[df.year == 1952].lifeExp.mean() # 效果同上
分组转换
概述
- transform 需要把DataFrame中的值传递给一个函数, 而后由该函数"转换"数据。
- 即: aggregate(聚合) 返回单个聚合值,但transform 不会减少数据量
# 需求1: 计算z-score(也叫: z分数, 标准分数), 即: (x - 平均值) / 标准差
def my_zscore(x):
# (每一组的值 - 当前组的平均值) / 当前组的标准差
return (x-x.mean())/x.std()
# 按年分组 计算z-score
df.groupby('year').lifeExp.transform(my_zscore)
# 查看数据集条目数, 跟之前transform处理之后的条目数一样
df.shape # 1704行, 6列
分组过滤
概述
- 使用groupby方法还可以过滤数据
- 调用filter 方法,传入一个返回布尔值的函数,返回False的数据会被过滤掉
# 需求: 根据就餐人数进行分组, 过滤掉条目数少于30条的组
# 1. 使用小费数据
tips = pd.read_csv('data/tips.csv')
# 2. 查看用餐人数
tips['size'].value_counts()
# 3. 人数为1、5和6人的数据比较少,考虑将这部分数据过滤掉
tips_filtered = tips.groupby('size').filter(lambda x: x['size'].count() > 30)
# 4. 查看结果
tips_filtered['size'].value_counts()
# 5. 合并版写法
tips.groupby('size').filter(lambda x: x['size'].count() > 30)['size'].value_counts()
DataFrameGroupby对象
概述
- 调用了groupby方法之后, 就会返回一个DataFrameGroupby对象
- python 中 是datetime pandas 中 是 Datetime64 和 Timestamp 时间戳类型
日期类型处理
Pandas日期时间类型简介
概述
- 和其它语言类似, Python内置了datetime对象,可以在datetime库中找到
- pandas的日期时间类型默认是 datetime64[ns]
日期时间类型相关操作
时间类型对象.year 获取年
时间类型对象.month 获取月
时间类型对象.day 获取日
时间类型对象.dayofyear 获取年中第几天
读取数据时 可以通过 parse_dates = [列的编号 列名] 来设置时间类型
可以通过 pd.date_range(开始时间,结束时间,freq = '生成规则')来生成指定区间的日期序列
生成规则如下:
Matplotlib 数据可视化
Matplotlib的API介绍
Matplotlib提供了两种方法来作图:**状态接口和面向对象
导包方式
# Matplotlib.pyplot 包含一系列绘图函数的相关函数
import matplotlib.pyplot as plt
创建画布方法
plt.figure() 参数 figsize 画布大小
方式1 : 状态接口
# 1. 准备x轴 和 y轴的数据.
x = [-3, 5, 7] # x轴坐标
y = [10, 2, 5] # y轴坐标
# 2. 创建画布, figure: 创建画布, figsize=指定画布大小
plt.figure(figsize=(15, 6))
# 3. 绘图, 传入x轴, y轴
plt.plot(x, y)
plt.grid(True) # 添加网格线
# 4. 设置x轴坐标 和 y轴坐标的范围
plt.xlim(0, 10)
plt.ylim(-3, 8)
# 5. 设置x轴 和 y轴的标签
plt.xlabel('X Axis', size=20)
plt.ylabel('Y Axis', size=10)
# 6. 设置标题.
plt.title('Line Plot', size=30)
# 7. 显示图片
plt.show()
方式2 面向对象
# 面向对象 绘图.
import matplotlib.pyplot as plt
# 1. 准备x轴 和 y轴的数据.
x = [-3, 5, 7] # x轴坐标
y = [10, 2, 5] # y轴坐标
# 2. 创建画布, 坐标轴对象
fig, ax = plt.subplots(figsize=(15, 6))
# 3. 绘图, 传入x轴, y轴
ax.plot(x, y)
ax.grid(True) # 添加网格线
# 4. 设置x轴坐标 和 y轴坐标的范围
ax.set_xlim(0, 10)
ax.set_ylim(-3, 8)
# 5. 设置x轴 和 y轴的标签
ax.set_xlabel('X Axis', size=20)
ax.set_ylabel('Y Axis', size=10)
# 6. 设置标题.
ax.set_title('Line Plot', size=30)
# 7. 显示图片
plt.show()