数据分析之Pandas
- 一、Pandas介绍 (数据处理工具)
- (一)Pandas优势
- (二)DataFrame
- (三)Series
- (一)缺失值处理
- (二)数据离散化
- (三)合并表格
- (四)交叉表
- (五)分组聚合【df.groupby(by=)】
一、Pandas介绍 (数据处理工具)
(一)Pandas优势
- 便捷的数据处理能力
- 读取文件方便
- 封装了Matplotlib、Numpy的画图和计算
(二)DataFrame
既有行索引,又有列索引的二维数组
- 创建
import numpy as npimport pandas as pd#准备数据stock_change = np.random.normal(0, 1, (10, 5))#准备索引stock = [\"股票{}\".format(i) for i in range(10)]date = pd.date_range(start=\"20180101\", periods=5, freq=\"B\")# 添加行列索引data = pd.DataFrame(stock_change, index=stock, columns=date)
df = pd.DataFrame({\'month\': [1, 4, 7, 10],\'year\': [2012, 2014, 2013, 2014],\'sale\':[55, 40, 84, 31]})
- 常用属性和方法
- 属性
属性 | 描述 |
---|---|
shape | 大小 |
index | 行索引 |
columns | 列索引 |
values | 数据 |
T | 转置 |
- 方法
方法 | 描述 |
---|---|
head(num) | 前num条 |
tail(num) | 倒数num条数据 |
- DataFrame索引的设置
注意: 不能单独修改索引,如:data.index[3] = “票58”
- 1)修改行列索引值
stock_ = [\"股票_{}\".format(i) for i in range(10)]data.index = stock # stock为列表
- 2)重设索引
data.reset_index(drop=False)#去除原索引,变为随机索引;如果drop=True,则将原索引列删除
- 3)设置新索引
df.set_index(\"列索引01\", drop=False)#将列索引01设置为索引,drop=False可以实现保存原列在数据列之中new_df = df.set_index([\"year\", \"month\"])#设置多个,此时new_df.index返回MultiIndex,相当于DataFrame的容器。包含names(\"year\", \"month\")和levels(\"year\", \"month\"的值)属性new_df.index.namesnew_df.index.levels
(三)Series
- 创建
# 1. 从DataFrame截取sr = data.iloc[1, :]# 2. 一维数组创建pd.Series(np.arange(3, 9, 2), index=[\"a\", \"b\", \"c\"])# 3. 字典pd.Series({\'red\':100, \'blue\':200, \'green\': 500, \'yellow\':1000})
- 操作
- sr.index
- sr.values
二、基本数据操作
- 删除指定列
data = data.drop([\"ma5\",\"ma10\",\"ma20\",\"v_ma5\",\"v_ma10\",\"v_ma20\"], axis=1)
- 索引操作
注意:data[1, 0] 不能直接进行数字索引
- 1)直接索引【先列后行】
data[\"列索引01\"][\"行索引01\"]
- 2)按名字索引【loc】
data.loc[\"行索引01\"][\"列索引01\"]data.loc[\"行索引01\",\"列索引01\"]
- 3)按数字索引【iloc】
data.iloc[1, 0]
- 4)组合索引【ix】(数字、名字)
data.ix[:4, [\'open\', \'close\', \'high\', \'low\']]
- 赋值
data.open = 100 # 按列来赋值,open为列索引data.iloc[1, 0] = 222 # 按索引来赋值
- 排序
- 对内容排序
data.sort_values(by=[\"high\", \"p_change\"], ascending=False).head()sr.sort_values(ascending=False).head()
- 对索引排序
data.sort_index().head()sr.sort_index().head()
- 算数运算
data[\"列索引01\"].add(3).head()data.sub(100).head()data[\"列索引01\"].sub(data[\"列索引02\"]).head()
- 逻辑运算<、 >、|、 &
- 布尔索引
data[data[\"p_change\"] > 2].head()# 完成一个多个逻辑判断, 筛选p_change > 2并且low > 15data[(data[\"p_change\"] > 2) & (data[\"low\"] > 15)].head()
- 逻辑运算函数【query()】【 isin()】
data.query(\"p_change > 2 & low > 15\").head()data[data[\"turnover\"].isin([4.19, 2.39])]
- 统计运算【min max mean median var std】
如Numpy【np.argmax()】【np.argmin()】
data.describe()data.max(axis=0)data.idxmax(axis=0)# 最大值对应的行索引值
- 累计统计函数
data[\"列索引01\"].sort_index().cumsum().plot()
- 自定义运算【apply(func, axis=0)】 func:自定义函数
data.apply(lambda x: x.max() - x.min())
- Pandas画图【sr.plot()】
data.plot(x=\"列01\", y=\"列02\", kind=\"scatter\")
- CSV文件读取与存储
【pd.read_csv(path), usecols=,names=】
pd.read_csv(\"./stock_day/stock_day.csv\", usecols=[\"high\", \"low\", \"open\", \"close\"]).head()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\"])
【dataframe.to_csv(path,columns=[],index=False, header=False)】
data[:10].to_csv(\"test.csv\", columns=[\"open\"], index=False, mode=\"a\", header=False)
二、pandas简单数据处理
(一)缺失值处理
- 缺失值为nan
- 判断是否有空值
import pandas as pdimport numpy as np# pd.isnull(movie)放回全数据的bool形式pd.isnull(movie).any()#返回True,说明数据中存在缺失值【按列显示】pd.notnull(movie).all()# 返回False,说明数据中存在缺失值【按列显示】#采用Numpy形式判断是否为空np.any(pd.isnull(movie)) # 返回True,说明数据中存在缺失值np.all(pd.notnull(movie)) # 返回False,说明数据中存在缺失值
- 缺失值处理方式
# 1. 删除data1 = data.dropna()# 2. 补全data[\"列\"].fillna(data[\"列\"].mean(), inplace=True) # inplace=True改变原数据
- 缺失值不为nan
# 1. 替换data_new = data.replace(to_replace=\"?\", value=np.nan)# 将‘?’替换为nan# 1. 删除# 2. 补全
(二)数据离散化
- 自动分组【pd.qcut( Series, n )】
# 1)自动分为3组sr = pd.qcut(data, 3)# data为Series# 2)每个分组包含数据的countsr.value_counts()# 3)转换成one-hot编码pd.get_dummies(sr, prefix=\"wid\")
- 自定义分组【pd.cut( Series, list )】
# 1)自定义分组bins = [15, 16, 18, 19]sr = pd.cut(data, bins)# 2)每个分组包含数据的countsr.value_counts()# 3)转换成one-hot编码pd.get_dummies(sr, prefix=\"wid\")
(三)合并表格
1. 按方向合并【 pd.concat( [], axis= ) 】axis=决定方向
pd.concat([表名01, 表名02], axis=1)# axis=1 在列后面追加
2. 按索引合并【pd.merge】
- how=“inner” 内连接的方式, on=[“key1”, “key2”] 按关键字
pd.merge(left, right, how=\"inner\", on=[\"key1\", \"key2\"])pd.merge(left, right, how=\"left\", on=[\"key1\", \"key2\"])
(四)交叉表
探究两列的数量关系。列01分组中的列02分布
# 交叉表data = pd.crosstab(data[\"列01\"], data[\"列02\"])data.div(data.sum(axis=1), axis=0).plot(kind=\"bar\", stacked=True)
(五)分组聚合【df.groupby(by=)】
注:groupby()后面需要搭配max、count等统计函数才能显示
# 用dataframe的方法进行分组data.groupby(by=\"列01\")[\"列02\"].max()#按列01分组,然后去出列02的最大值data.groupby(\"列01\").count()[\"列02\"].sort_values(ascending=False)[:10].plot(kind=\"bar\", figsize=(20, 8), fontsize=40)data.groupby(by=[\"列1\", \"列2\"]).count()#多列分组np.unique(data[\"列\"]).size # 列中不同的元素个数