Bootstrap

机器学习入门:准备知识笔记(pandas)之二

参考教学笔记:2021年Python人工智能,13天机器学习入门到精通,精讲+14大案例分析(数据来源参考

 Pandas画图

1 pandas.DataFrame.plot
DataFrame.plot (kind='line')
kind : str, 需要绘制图形的种类
‘line’ : line plot (default)
‘bar’ : vertical bar plot
‘barh’ : horizontal bar plot
关于“barh”的解释:
http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.barh.html
‘hist’ : histogram
‘pie’ : pie plot
‘scatter’ : scatter plot
更多细节: https://pandas.pydata.org/pandasdocs/stable/generated/pandas.DataFrame.plot.html?
highlight=plot#pandas.DataFrame.plot

2 pandas.Series.plot
更多细节: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.html?highlight=plot#pandas.Series.plot


文件读取与存储

pandas的API支持众多的文件格式, 如CSV、 SQL、 XLS、 JSON、
HDF5。注: 最常用的HDF5和CSV文件

1 CSV
1.1 read_csv
pandas.read_csv(filepath_or_buffer, sep =',', usecols )
filepath_or_buffer:文件路径
sep :分隔符, 默认用","隔开
usecols:指定读取的列名, 列表形式
举例: 读取之前的股票的数据
# 读取文件,并且指定只获取'open', 'close'指标
data = pd.read_csv("./data/stock_day.csv", usecols=['open', 'close'])
open close
2018-02-27 23.53 24.16
2018-02-26 22.80 23.53
2018-02-23 22.88 22.82
2018-02-22 22.25 22.28
2018-02-14 21.49 21.92


1.2 to_csv
DataFrame.to_csv(path_or_buf=None, sep=', ’, columns=None, header=True, index=True, mode='w', encoding=None)
path_or_buf :文件路径
sep :分隔符, 默认用","隔开
columns :选择需要的列索引
header :boolean or list of string, default True,是否写进列索引值

index:是否写进行索引
mode:'w': 重写, 'a' 追加


举例: 保存读取出来的股票数据
保存'open'列的数据, 然后读取查看结果
# 选取10行数据保存,便于观察数据
data[:10].to_csv("./data/test.csv", columns=['open'])
# 读取, 查看结果
pd.read_csv("./data/test.csv")
Unnamed: 0 open
0 2018-02-27 23.53
1 2018-02-26 22.80
2 2018-02-23 22.88
3 2018-02-22 22.25
4 2018-02-14 21.49
5 2018-02-13 21.40
6 2018-02-12 20.70
7 2018-02-09 21.20
8 2018-02-08 21.79
9 2018-02-07 22.69

会发现将索引存入到文件当中, 变成单独的一列数据。 如果需要删除, 可以指定index参数,删除原来的文件, 重新保存一次。
# index:存储不会讲索引值变成一列数据
data[:10].to_csv("./data/test.csv", columns=['open'], index=False)

2 HDF5
2.1 read_hdf与to_hdf
HDF5文件的读取和存储需要指定一个键, 值为要存储的DataFrame
pandas.read_hdf(path_or_buf, key =None, ** kwargs)
从h5文件当中读取数据
path_or_buffer:文件路径
key:读取的键
return:Theselected object
DataFrame.to_hdf(path_or_buf, key, *\kwargs*)


2.2 案例
读取文件
day_close = pd.read_hdf("./data/day_close.h5")
如果读取的时候出现以下错误

需要安装安装tables模块避免不能读取HDF5文件
pip install tables

存储文件
day_close.to_hdf("./data/test.h5", key="day_close")
再次读取的时候, 需要指定键的名字
new_close = pd.read_hdf("./data/test.h5", key="day_close")
注意: 优先选择使用HDF5文件存储
HDF5在存储的时候支持压缩, 使用的方式是blosc, 这个是速度最快的也是pandas默认支持的
使用压缩可以提磁盘利用率, 节省空间
HDF5还是跨平台的, 可以轻松迁移到hadoop 上面

3 JSON
JSON是我们常用的一种数据交换格式, 前面在前后端的交互经常用到, 也会在存储的时候选择这种格式。 所以我们需要知道Pandas如何进行读取和存储JSON格式。
3.1 read_json
pandas.read_json(path_or_buf=None, orient=None, typ='frame', lines=False)

将JSON格式准换成默认的Pandas DataFrame格式
orient : string,Indication of expected JSON string format.
'split' : dict like {index -> [index], columns -> [columns], data -> [values]}
split 将索引总结到索引, 列名到列名, 数据到数据。 将三部分都分开了
'records' : list like [{column -> value}, ... , {column -> value}]
records 以 columns: values 的形式输出
'index' : dict like {index -> {column -> value}}
index 以 index: {columns: values}... 的形式输出
'columns' : dict like {column -> {index -> value}},默认该格式
colums 以 columns:{index:values} 的形式输出
'values' : just the values array
values 直接输出值
lines : boolean, default False
按照每行读取json对象
typ : default ‘frame’, 指定转换成的对象类型series或者dataframe

3.2 read_josn 案例
数据介绍
这里使用一个新闻标题讽刺数据集, 格式为json。 is_sarcastic : 1讽刺的, 否则为0; headline : 新闻报道的标题; article_link : 链接到原始
新闻文章。 存储格式为:
{"article_link": "https://www.huffingtonpost.com/entry/versace-black-code_us_5861fbefe4b0de3a08f600d5", "headline": "former versace store clerk sue
s over secret 'black code' for minority shoppers", "is_sarcastic": 0}
{"article_link": "https://www.huffingtonpost.com/entry/roseanne-revival-review_us_5ab3a497e4b054d118e04365", "headline": "the 'roseanne' revival ca
tches up to our thorny political mood, for better and worse", "is_sarcastic": 0}
读取
orient指定存储的json格式, lines指定按照行去变成一个样本
json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
结果为:

3.3 to_json
DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
将Pandas 对象存储为json格式
path_or_buf=None: 文件地址
orient:存储的json形式, {‘split’,’records’,’index’,’columns’,’values’}
lines:一个对象存储为一行


高级处理-缺失值处理

1 如何处理nan
获取缺失值的标记方式(NaN或者其他标记方式)
如果缺失值的标记方式是NaN
判断数据中是否包含NaN:
pd.isnull(df),
pd.notnull(df)

存在缺失值nan:
1、 删除存在缺失值的:dropna(axis='rows')
注: 不会修改原数据, 需要接受返回值
2、 替换缺失值:fillna(value, inplace=True)
value:替换成的值
inplace:True:会修改原数据, False:不替换修改原数据, 生成新的对象
如果缺失值没有使用NaN标记, 比如使用"? "
先替换‘?’为np.nan, 然后继续处理

2 电影数据的缺失值处理

电影数据文件获取
# 读取电影数据
movie = pd.read_csv("./data/IMDB-Movie-Data.csv")

2.1 判断缺失值是否存在
pd.notnull()


pd.notnull(movie)
Rank Title Genre Description Director Actors Year Runtime (Minutes) Rating Votes Revenue (Millions) Metascore
0 True True True True True True True True True True True True
1 True True True True True True True True True True True True
2 True True True True True True True True True True True True
3 True True True True True True True True True True True True
4 True True True True True True True True True True True True
5 True True True True True True True True True True True True
6 True True True True True True True True True True True True
7 True True True True True True True True True True False True
np.all(pd.notnull(movie))


pd.isnull()

2.2 存在缺失值nan,并且是np.nan
1、 删除
pandas删除缺失值, 使用dropna的前提是, 缺失值的类型必须是np.nan
# 不修改原数据
movie.dropna()

# 可以定义新的变量接受或者用原来的变量名
data = movie.dropna()
2、 替换缺失值
# 替换存在缺失值的样本的两列
# 替换填充平均值, 中位数
# movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(), inplace=True)
替换所有缺失值:
for i in movie.columns:
if np.all(pd.notnull(movie[i])) == False:
print(i)
movie[i].fillna(movie[i].mean(), inplace=True)

2.3 不是缺失值nan, 有默认标记的
数据是这样的:

 wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")
以上数据在读取时, 可能会报如下错误:
URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:833)>
解决办法:
# 全局取消证书验证
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

处理思路分析:
1、 先替换‘?’为np.nan
df.replace(to_replace=, value=)
to_replace:替换前的值
value:替换后的值

# 把一些其它值标记的缺失值, 替换成np.nan
wis = wis.replace(to_replace='?', value=np.nan)
2、 在进行缺失值的处理
# 删除
wis = wis.dropna()


高级处理-数据离散化

应用cut、 qcut实现数据的区间分组
应用get_dummies实现数据的one-hot编码

1 为什么要离散化
连续属性离散化的目的是为了简化数据结构, 数据离散化技术可以用来减少给定连续属性值的个数。 离散化方法经常作为数据挖掘的工具。
2 什么是数据的离散化
连续属性的离散化就是在连续属性的值域上, 将值域划分为若干个离散的区间, 最后用不同的符号或整数 值代表落在每个子区间中的属性值。
离散化有很多种方法, 这使用一种最简单的方式去操作
原始人的身高数据: 165, 174, 160, 180, 159, 163, 192, 184
假设按照身高分几个区间段: 150~165, 165~180,180~195
这样我们将数据分到了三个区间段, 我可以对应的标记为矮、 中、 高三个类别, 最终要处理成一个"哑变量"矩阵

3 股票的涨跌幅离散化
我们对股票每日的"p_change"进行离散化,目标样式如下

 3.1 读取股票的数据
先读取股票的数据, 筛选出p_change数据
data = pd.read_csv("./data/stock_day.csv")
p_change= data['p_change']

3.2 将股票涨跌幅数据进行分组

使用的工具:
pd.qcut(data, q):
对数据进行分组将数据分组, 一般会与value_counts搭配使用, 统计每组的个数
series.value_counts(): 统计分组次数
# 自行分组
qcut = pd.qcut(p_change, 10)
# 计算分到每个组数据个数
qcut.value_counts()
自定义区间分组:
pd.cut(data, bins)
# 自己指定分组区间
bins = [-100, -7, -5, -3, 0, 3, 5, 7, 100]
p_counts = pd.cut(p_change, bins)

3.3 股票涨跌幅分组数据变成one-hot编码
什么是one-hot编码
把每个类别生成一个布尔列, 这些列中只有一列可以为这个样本取值为1.其又被称为独热编码。

例如;

pandas.get_dummies(data, prefix=None)
data:array-like, Series, or DataFrame

prefix:分组名字
# 得出one-hot编码矩阵
dummies = pd.get_dummies(p_counts, prefix="rise")

得到我们想要的目标样式


高级处理-合并

1 pd.concat实现数据合并
pd.concat([data1, data2], axis=1)
按照行或列进行合并,axis=0为列索引, axis=1为行索引
比如我们将刚才处理好的one-hot编码与原数据合并


# 按照行索引进行
pd.concat([data, dummies], axis=1)

2 pd.merge
pd.merge(left, right, how='inner', on=None)
可以指定按照两组数据的共同键值对合并或者左右各自
left : DataFrame
right : 另一个DataFrame
on : 指定的共同键
how:按照什么方式连接

2.1 pd.merge合并
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
# 默认内连接
result = pd.merge(left, right, on=['key1', 'key2']) 

左连接
result = pd.merge(left, right, how='left', on=['key1', 'key2'])

右连接
result = pd.merge(left, right, how='right', on=['key1', 'key2']) 

 

外链接
result = pd.merge(left, right, how='outer', on=['key1', 'key2'])

 

 

;