机器学习Day2——Pandas的使用

本栏目为本人自学B站各位好心的博主所录视频过程中记录下来的笔记,出处基本来自于B站视频博主以及csdn中各位大佬的解释,我只起到了转载的作用。因来源过于复杂,因此无法标注来源。

此篇数据分析文章的内容均来自于Bilibili的黑马程序员的数据挖掘的课程,本人仅起到总结的作用

1.pandas包

1.1 什么是pandas

  1. 专门用于数据挖掘的开源python库
  2. 以Numpy为基础,借力Numpy模块在计算方面性能高的优势
  3. 基于matplotlib,能够简便的画图
  4. 具有独特的数据结构

1.2 为什么要使用pandas

Numpy已经能够帮助我们处理数据,能够结合matplotlib解决部分数据展示等问题,那么pandas学习的目的在什么地方呢?

  1. 便捷的数据处理能力
  2. 读取文件方便
  3. 封装了Matplotlib、Numpy的画图和计算

1.3 DataFrame

在正式开始学习前,不妨举个易于理解的例子:

回顾学习Numpy时随机生成数组,那时的数组只是人为的赋予其含义,并未给予形式上的定义,也就是说让其他人来看,并不知道行和列各自代表着什么意思,而pandas中的DataFrame数据结构就可以生成一张带有行列含义的二维表

import numpy as np
# 创建一个符合正态分布的10个股票5天的涨跌幅数据
stock_change = np.random.normal(0, 1, (10, 5))

import pandas as pd
pd.DataFrame(stock_change)

pd.DataFrame(stock_change)的值如下所示,返回的是一个带有行列索引的二维表:
在这里插入图片描述

# 添加行索引
stock = ["股票{}".format(i) for i in range(10)]
pd.DataFrame(stock_change, index=stock)
# 添加列索引
date = pd.date_range(start="20180101", periods=5, freq="B")
data = pd.DataFrame(stock_change, index=stock, columns=date)

那么如今的data值为:
在这里插入图片描述

1.3.1 DataFrame的属性

data.shape       # 返回几行几列
data.index		 # 返回行索引
data.columns	 # 返回列索引
data.values		 # 返回不带行列索引的二维数组
data.T			 # 返回转置的数组
data.head(3)	 # 取数组的前三条记录
data.tail(2)	 # 取数组的最后2条记录

1.3.2 DataFrame的行列索引的修改

  • 修改行列索引

DataFrame中的行列索引并不能直接通过访问下标的形式来赋值修改。若要修改某一个值,则需要将整个行或列索引全部修改。

  • 重设索引
data.reset_index(drop=False)
  • 设置新索引
df = pd.DataFrame({'month': [1, 4, 7, 10],
                    'year': [2012, 2014, 2013, 2014],
                    'sale':[55, 40, 84, 31]})
# 设月为索引
df.set_index("month", drop=True)
# 设年、月为索引
new_df = df.set_index(["year", "month"])

1.4 MultiIndex与Panel

1.4.1 MultiIndex

多级或分层索引对象。

  • index属性
    • names:levels的名称
    • levels:每个level的元组值
new_df.index
#其类型为:
MultiIndex(levels=[[2012, 2013, 2014], [1, 4, 7, 10]],
           labels=[[0, 2, 1, 2], [0, 1, 2, 3]],
           names=['year', 'month'])

1.4.2 Panel

已弃用

1.4.3 Series

可以简单的理解为:带索引的一维数组。

sr = data.iloc[1, :]

# sr的样式为:
2018-01-01    0.283614
2018-01-02    0.431016
2018-01-03   -0.771543
2018-01-04    0.482862
2018-01-05   -0.307247
Freq: B, Name: 股票_1, dtype: float64

sr.index
# sr.index的样式为:
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
               '2018-01-05'],
              dtype='datetime64[ns]', freq='B')

sr.values
# sr.values的样式为:
array([ 0.28361364,  0.43101642, -0.77154311,  0.48286211, -0.30724683])

type(sr.values)
# type(sr.values)的值为:
numpy.ndarray

pd.Series(np.arange(3, 9, 2), index=["a", "b", "c"])
# 显示效果为:
a    3
b    5
c    7
dtype: int64

1.4 基本数据操作

1.4.1 索引操作

  1. 直接使用行列索引(先列后行)
    行列索引不一定为整形,也有可能为字符创类型
  2. 按名字索引
data.loc["2018-02-26", "open"]
  1. 按数字索引(行,列)
data.iloc[1, 0]

1.4.2 赋值操作

data.列索引 = 100
data.iloc[1,0] = 300

1.4.3 排序操作

  1. 对内容排序

DataFrame

  • 使用df.sort_values(key=,ascending=)对内容进行排序。
    • 单个键或者多个键进行排序默认升序
    • ascending=False : 降序
    • ascending=True : 升序
data.sort_values(by=["high", "p_change"], ascending=False)

Series

  • 使用Series.sort_values(ascending=)对内容进行排序。
    • ascending=False : 降序
    • ascending=True : 升序
sr.sort_values(ascending=False)
  1. 对索引排序

DataFrame

  • 使用df.sort_index对索引进行排序
data.sort_index()

Series

  • 使用Series.sort_index对索引进行排序
sr.sort_index()

1.5 DataFrame运算

本部分所采用的数据节选如下:
在这里插入图片描述

1.5.1 算术运算

data["open"].add(3)
data.sub(100)
data["close"].sub(data["open"])

1.5.2 逻辑运算

data[data["p_change"] > 2]
data[(data["p_change"] > 2) & (data["low"] > 15)]
data.query("p_change > 2 & low > 15")
data[data["turnover"].isin([4.19, 2.39])]  #判断值是否为4.19或2.39

1.5.3 统计运算

data.describe()  #计算出每列的count、mean、std、min、25%、50%、75%、max
data.max(axis = 0)  #0为列,1为行
data.min()
data.std()
data.idxmax()  #最大值的下标
data.idxmin()  #最小值的下标
...
  • 累计统计函数
函数作用
cumsum计算前1/2/3/…/n个数的和
cummax计算前1/2/3/…/n个数的最大值
cummin计算前1/2/3/…/n个数的最小值
cumprod计算前1/2/3/…/n个数的积
data["p_change"].sort_index().cumsum().plot()

1.5.4 自定义运算

  • apply(func, axis=0)
    • func:自定义函数
    • axis=0:默认是列,axis = 1为行进行运算
  • 定义一个对列,最大值-最小值的函数
data.apply(lambda x: x.max() - x.min(), axis = 0)

1.6 DataFrame画图

  • DataFrame.plot (x=None, y=None, kind=“line”)
    • x : label or position, default None
    • y : label,position or list of label, positions, default None
      • Allows plotting of one column versus another
    • kind : str
      • ‘line’: line plot (default)
      • ‘bar’ : vertical bar plot
      • ‘barh’ : horizontal bar plot
      • ‘hist’ : histogram
      • ‘pie’ : pie plot
      • ‘scatter’ : scatter plot

1.7 文件的读取与存储

1.7.1 CSV文件

#仅读取"high", "low", "open", "close"四列
pd.read_csv("./stock_day/stock_day.csv", usecols=["high", "low", "open", "close"])

#name字段可以为纯数据的文件数据设置表头
data = pd.read_csv("stock_day2.csv", names=["open", "high", "close", "low", "volume", "price_change", "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"])

#将数据存为csv文件,读取数据中的“open”列,写入行索引,追加模式写入,写入列索引
data[:10].to_csv("D:/test.csv", columns=["open"], index=False, mode="a", header=False)

1.7.2 HDF5文件

#读取hdf5文件
day_close = pd.read_hdf("./stock_data/day/day_close.h5")
#存储hdf5形式的文件,必须要指定key的值
day_close.to_hdf("test.h5", key="close")
#再次读入hdf5形式的文件
pd.read_hdf("test.h5", key="close")

1.7.1 JSON文件

# orient以什么形式读取  lines是否按行读取
sa = pd.read_json("Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
#存储为json
sa.to_json("test.json", orient="records", lines=True)

1.8 Pandas高级数据处理

1.8.1 缺失值处理

  • 丢弃
  • 替换或插补
  1. 判断数据是否为NaN :
    • pd.isnull(df)或pd.notnull(df)

处理方式:

  1. 存在缺失值NaN ,并且是np.NaN :
    • 1.删除存在缺失值的:dropna(axis=“rows”)
      • 注:不会修改原数据,需要接受返回值。
    • 2.替换缺失值:fillna(value, inplace=True)
      • value:替换成的值
      • inplace:
        • True:会修改原数据
        • False:不替换修改原数据,生成新的对象
np.any(pd.isnull(movie))  # 返回True,说明数据中存在缺失值
np.all(pd.notnull(movie)) # 返回False,说明数据中存在缺失值
pd.isnull(movie).any() 	  # 返回存在缺失值的字段
pd.notnull(movie).all()   # 返回存在缺失值的字段

# 方法1:删除含有缺失值的样本
data1 = movie.dropna()

# 方法2:替换,用平均值替换
# 含有缺失值的字段:Revenue (Millions),Metascore
movie["Revenue (Millions)"].fillna(movie["Revenue (Millions)"].mean(), inplace=True)
movie["Metascore"].fillna(movie["Metascore"].mean(), inplace=True)
  1. 不是缺失值NaN ,有默认标记的
    即数据不表示为NaN,而是表示为特殊标记,如?的数据。

    • 1.替换?为NaN
    • 2.处理NaN数据
# 1)替换
data_new = data.replace(to_replace="?", value=np.nan)
# 2)删除缺失值
data_new.dropna(inplace=True)

1.8.2 数据离散化

连续属性的离散化就是在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数值代表落在每个子区间中的属性值。

  • 1)分组
    • 自动分组sr=pd.qcut(data, bins)
    • 自定义分组sr=pd.cut(data, [])
  • 2)将分组好的结果转换成one-hot编码
    • pd.get_dummies(sr, prefix=)
# 1)分组,自动分组
sr = pd.qcut(data, 3)
# 2)转换成one-hot编码
pd.get_dummies(sr, prefix="height")

# 1)分组,自定义分组
bins = [150, 165, 180, 195]
sr = pd.cut(data, bins)
# 2)转换成one-hot编码
pd.get_dummies(sr, prefix="身高")

1.8.3 合并

  1. 按方向拼接
pd.concat([stock, stock_change], axis=1)   # 1为水平拼接,0为垂直拼接
  1. 按索引拼接
pd.merge(left, right, how="inner", on=["key1", "key2"])  #内连接
pd.merge(left, right, how="left", on=["key1", "key2"])  #左外连接
pd.merge(left, right, how="outer", on=["key1", "key2"])  #外连接

1.8.4 交叉表与透视表

  1. 交叉表(crosstable)
  • 交叉表:交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个到之间的关系)
    • pd.crosstab(value1, value2)
# 星期数据以及涨跌幅是好是坏数据
# pd.crosstab(星期数据列, 涨跌幅数据列)
# 准备星期数据列
# pandas日期类型
date = pd.to_datetime(stock.index)
stock["week"] = date.weekday
# 准备涨跌幅数据列
stock["pona"] = np.where(stock["p_change"] > 0, 1, 0)
# 交叉表,此刻得到的是频数
data = pd.crosstab(stock["week"], stock["pona"])
# 求频率
new_data = data.div(data.sum(axis=1), axis=0)
# 制成图表
new_data.plot(kind="bar", stacked=True)
  1. 透视表(pivot_table)
# 透视表操作
stock.pivot_table(["pona"], index=["week"])

1.8.5 分组与聚合

col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})
# 进行分组,对颜色分组,price1进行聚合
# 	1.用dataframe的方法进行分组
col.groupby(by="color")["price1"].max()
# 	2.用Series的方法进行分组
col["price1"].groupby(col["color"]).max()
  • 案例分析,统计每个国家及其省份的星巴克门店数量
# 1、准备数据
starbucks = pd.read_csv("directory.csv")
# 2、按照国家分组,求出每个国家的星巴克零售店数量并绘制柱状图
starbucks.groupby("Country").count()["Brand"].sort_values(ascending=False)[:10].plot(kind="bar", figsize=(20, 8), fontsize=40)
# 3、加入省市一起进行分组
starbucks.groupby(by=["Country", "State/Province"]).count()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值