Pandas

Pandas的数据结构
学习目标
目标
了解Numpy与Pandas的不同
说明Pandas的Series与Dataframe两种结构的区别
了解Pandas的MultiIndex与panel结构
应用
股票涨跌幅数据的修改
1、Pandas介绍
pandas

2008年WesMcKinney开发出的库
专门用于数据挖掘的开源python库
以Numpy为基础,借力Numpy模块在计算方面性能高的优势
基于matplotlib,能够简便的画图
独特的数据结构
2、为什么使用Pandas
Numpy已经能够帮助我们处理数据,能够结合matplotlib解决部分数据展示等问题,那么pandas学习的目的在什么地方呢?

便捷的数据处理能力
处理前

处理后

Pandas的重要性
对于数据的处理,如果没有pandas,那么可能python就在数据挖掘/机器学习领域领域落后于R

那么在说大数据可能我们可能会听过Hadoop和Spark,它们的有时是基于集群的云端处理数据,如果数据只有几GB,甚至1~2TB,那么pandas也是处理数据的最好选择

回忆我们在numpy当中创建的股票涨跌幅数据形式?

创建一个符合正太分布的500个股票504天的涨跌幅数据

stock_day_rise = np.random.normal(0, 1, (500, 504))
array([[-1.47580291, -1.6171524 , -0.3065993 , …, 0.33796194,
-0.08529695, 0.4951836 ],
[-0.15815135, -0.49150059, -0.90192837, …, -0.58003107,
0.06213526, -0.48994794],
[ 0.09761985, -0.30173525, -2.01897218, …, -1.34711536,
-1.15597236, -0.6623075 ],
…,
[-0.43274532, -1.01644526, 0.16935745, …, -0.40709199,
0.23301604, -0.43792918],
[-0.57734276, 2.30413166, 1.29008026, …, -0.54980277,
-1.00555547, 1.79315772],
[-1.47725321, 0.1392723 , -0.09880384, …, 0.57230664,
-0.75429618, -0.4396632 ]])
但是这样的数据形式很难看到存储的是什么的样的数据,并也很难获取相应的数据,比如需要获取某个指定股票的数据,就很难去获取!!

问题:如何让数据更有意义的显示?
3、Pandas的数据结构
3.1三大结构
Pandas有三大数据结构,Series、DataFrame以及Panel。

Series(一维数据)
DataFrame(二维数据)
Panel(三维结构数据/面板数据)
注释:对于Panel,会很少使用,通常会使用使用MultiIndex这种结构解决三维数据表示问题

3.2处理刚才的股票数据

使用Pandas中的数据结构

stock_day_rise = pd.DataFrame(stock_day_rise)
使用df包裹涨跌幅数据

3.3初识DataFrame
DataFrame对象既有行索引,又有列索引

行索引,表明不同行,横向索引,叫index,0轴,axis=0
列索引,表名不同列,纵向索引,叫columns,1轴,axis=1
df

3.4给股票涨跌幅数据增加行列索引
效果:

stockdf

增加行索引
#构造行索引索引序列
stock_code = [‘股票’ + str(i) for i in range(stock_day_rise.shape[0])]

添加行索引

data = pd.DataFrame(stock_day_rise, index=stock_code)
增加列索引
股票的日期是一个时间的序列,我们要实现从前往后的时间还要考虑每月的总天数等,不方便。

使用pd.date_range():用于生成一组连续的时间序列(暂时了解)

date_range(start=None,end=None, periods=None, freq=‘B’)

start:开始时间

end:结束时间

periods:时间天数

freq:递进单位,默认1天,'B'默认略过周末

生成一个时间的序列,略过周末非交易日

date = pd.date_range(‘2017-01-01’, periods=stock_day_rise.shape[1], freq=‘B’)

index代表行索引,columns代表列索引

data = pd.DataFrame(stock_day_rise, index=stock_index, columns=date)
3.5DatatFrame的属性
shape

dtypes

ndim
index
columns
values
T
还有一些方便整体查询的属性

head(5)
tail(5)
3.5DatatFrame索引的设置
修改行列索引值

修改行列索引值

data.index[499] = “0000001.SH” # 无法修改

通过整体修改,不能单个赋值

data.index = [i for i in range(500)]
重设索引

重置索引

data.reset_index(drop=True)
以某列值设置为新的索引
df = pd.DataFrame({‘month’:[1,4,7,10], ‘year’:[1, 1, 2, 2], ‘sale’:[55, 40, 84, 31]})

df.set_index([‘month’])# 设置新的索引值,但是返回一个新的dataframe

df = df.set_index([‘month’])

设置多重索引 MultiIndex的结构

df.set_index([‘year’, df.index])

打印df的索引

df.index
注:通过刚才的设置,这样DataFrame就变成了一个具有MutiIndex的DataFrame。后面会详细介绍这样的结构

如果获取某个股票的不同时间数据?这样的结构是什么样的?
3.6Series结构
什么是Series结构呢,我们直接看下面的图:

series

series结构只有行索引
我们将之前的涨跌幅数据进行转置,然后获取’股票0’的所有数据

series

type(data[‘股票0’])

这一步相当于是series去获取行索引的值

data[‘股票0’][‘2017-01-02’]
3.7创建series
通过已有数据创建

指定内容,默认索引
pd.Series(np.arange(10))
指定索引
pd.Series([6.7,5.6,3,10,2], index=)
通过字典数据创建

pd.Series({‘red’:100, '‘blue’:200, ‘green’: 500, ‘yellow’:1000})
3.8 series获取属性和值
index
values
4、小结
pandas的三种数据结构
dataframe和series的不同
基本数据操作
学习目标
目标
记忆DataFrame的形状、行列索引名称获取等基本属性
应用Series和DataFrame的索引进行切片获取
应用sort_index和sort_values实现索引和值的排序
应用
股票每日数据的操作
为了更好的理解这些基本操作,我们将读取一个真实的股票数据。关于文件操作,后面在介绍,这里只先用一下API

读取文件

data = pd.read_csv("./data/stock_day/stock_day.csv")
stockday

1、索引操作
Numpy当中我们已经讲过使用索引选取序列和切片选择,pandas也支持类似的操作,也可以直接使用列名、行名

称,甚至组合使用。

pandas的DataFrame的获取有三种形式

直接使用行列索引(先列后行)
结合loc或者iloc使用索引
使用ix组合索引

通过行列索引

data[‘open’][[‘2018-02-27’]]

使用loc

loc:只能指定行列索引的名字

data.loc[‘2018-02-27’:‘2018-02-22’, ‘open’]

使用iloc

使用iloc可以通过索引的下标去获取

data.iloc[0:100, 0:2].head()

使用ix进行下表和名称组合做引

data.ix[0:10, [‘open’, ‘close’]]

相当于

data[[‘close’, ‘open’, ‘high’]][0:3]
不支持的操作

错误

data[[‘2018-02-27’]][‘open’]

错误

data[:1, :2]
2、对于内容的操作

直接修改原来的值

data[‘close’] = 1

或者

data.close = 1
3、排序
排序有两种形式,一种对于索引进行排序,一种对于内容进行排序

使用df.sort_values(默认是从小到大)
单个键进行排序
多个键进行排序
使用df.sort_index给索引进行排序

按照涨跌幅大小进行排序 , 使用ascending指定按照大小排序

data = data.sort_values(by=‘p_change’, ascending=False)

按照过个键进行排序

data = data.sort_values(by=[‘open’, ‘high’])

对索引进行排序

data.sort_index()
统计分析
学习目标
目标
使用describe完成综合统计
使用max完成最大值计算
使用min完成最小值计算
使用mean完成平均值计算
使用std完成标准差计算
使用idxmin、idxmax完成最大值最小值的索引
使用cumsum等实现累计分析
应用
股票每日数据的统计
假设我们需要知道这个股票的某个指标的平均值????
1、基本统计分析函数
1.1、综合分析: describe()

计算平均值、标准差、最大值、最小值、分位数

data.describe()
1.2、单个函数分析
count Number of non-NA observations
sum Sum of values
mean Mean of values
mad Mean absolute deviation
median Arithmetic median of values
min Minimum
max Maximum
mode Mode
abs Absolute Value
prod Product of values
std Bessel-corrected sample standard deviation
var Unbiased variance
idxmax compute the index labels with the maximum
idxmin compute the index labels with the minimum
对于单个函数去进行统计的时候,坐标轴还是按照这些默认“index” (axis=0, default), “columns” (axis=1)指定

单独计算

data[‘close’].max()

对所有的列进行计算

data.max(0)

对所有的行进行计算

data.max(1)

求出最大值的位置

data.idxmax(axis=0)

求出最小值的位置

data.idxmin(axis=0)
2、累计统计分析函数
函数 作用
cumsum 计算前1/2/3/…/n个数的和
cummax 计算前1/2/3/…/n个数的最大值
cummin 计算前1/2/3/…/n个数的最小值
cumprod 计算前1/2/3/…/n个数的积
那么这些累计统计函数怎么用?
cumsum1

以上这些函数可以对series和dataframe操作

排序之后,进行累计求和

data = data.sort_index()

#计算累计函数
stock_rise = data[‘p_change’]

plot方法集成了前面直方图、条形图、饼图、折线图

stock_rise.cumsum()
那么如何让这个连续求和的结果更好的显示呢?
cumsum

如果要使用plot函数,需要导入matplotlib

import matplotlib.pyplot as plt
stock_rise.cumsum().plot()
plt.show()
关于plot: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.html?highlight=plot#pandas.DataFrame.plot
逻辑与算数运算
学习目标
目标
应用逻辑运算符号实现数据的逻辑筛选
应用isin实现数据的筛选
应用add等实现数据间的加法运算
应用apply函数实现数据的自定义处理
应用
实现股票的逻辑筛选
主要用于对股票的筛选操作
1、使用逻辑运算符号<、>等进行筛选

进行逻辑判断

用true false进行标记,逻辑判断的结果可以作为筛选的依据

data[data[‘p_change’] > 2]
2、使用|、&完成复合的逻辑

完成一个符合逻辑判断, p_change > 2, open > 15

data[(data[‘p_change’] > 2) & (data[‘open’] > 15)]
3、isin()

可以指定值进行一个判断,从而进行筛选操作

data[data[‘turnover’].isin([4.19])]
data.head(10)
4、数学运算
如果想要得到每天的涨跌大小?

进行数学运算 加上具体的一个数字

data[‘open’].add(1)

自己求出每天 close- open价格差

筛选两列数据

close = data[‘close’]
open1 = data[‘open’]

默认按照索引对齐

data[‘m_price_change’] = close.sub(open1)
5、自定义运算函数

进行apply函数运算

data[[‘open’, ‘close’]].apply(lambda x: x.max() - x.min(), axis=0)
data[[‘open’, ‘close’]].apply(lambda x: x.max() - x.min(), axis=1)
文件读取与存储
学习目标
目标
了解Pandas的几种文件读取存储操作
应用CSV方式和HDF方式实现文件的读取和存储
应用
实现股票数据的读取存储
我们的数据大部分存在于文件当中,所以pandas会支持复杂的IO操作,pandas的API支持众多的文件格式,如CSV、SQL、XLS、JSON、HDF5。

注:最常用的HDF5和CSV文件

1、数据读取存储API
读取存储

1.1 read_csv与to_csv
pandas.read_csv(filepath_or_buffer, sep =’,’ , delimiter = None)
filepath_or_buffer:文件路径
usecols:指定读取的列名,列表形式
DataFrame.to_csv(path_or_buf=None, sep=’, ’, columns=None, header=True, index=True, index_label=None, mode=‘w’, encoding=None)
path_or_buf :string or file handle, default None
sep :character, default ‘,’
columns :sequence, optional
mode:‘w’:重写, ‘a’ 追加
index:是否写进行索引
header :boolean or list of string, default True,是否写进列索引值

读取文件

data = pd.read_csv("./data/stock_day/stock_day.csv", usecols=[‘open’, ‘close’])

data[:10].to_csv("./test.csv", columns=[‘open’], index=False, mode=‘a’, header=False)
1.2、read_hdf与to_hdf
pandas.read_hdf(path_or_buf,key =None,** kwargs)

从h5文件当中读取数据

path_or_buffer:文件路径
key:读取的键
mode:打开文件的模式
return:Theselected object
close = pd.read_hdf("./data/stock_plot/day_close.h5")

a = close[[‘000001.SZ’, ‘000002.SZ’]]

a.to_hdf("./test.h5", key=“x”)
b = pd.read_hdf("./test.h5", key=“x”)
如果读取的时候出现以下错误

readh5

需要安装安装tables模块避免不能读取hdf文件

pip install tables
tables

拓展
优先选择使用hdf文件存储

hdf在存储的是支持压缩,使用的方式是blosc,这个是速度最快的也是pandas默认支持的
使用压缩可以提磁盘利用率,节省空间
hdf还是跨平台的,可以轻松迁移到hadoop 上面
高级处理-缺失值处理
学习目标
目标
说明Pandas的缺失值类型
应用replace实现数据的替换
应用dropna实现缺失值的删除
应用fillna实现缺失值的填充
应用isnull判断是否有缺失数据NaN
应用
对电影数据进行缺失值处理
如何处理缺失值?
缺失值

1、电影数据的缺失值处理
1.1 电影数据文件获取

读取电影数据

movie = pd.read_csv("./data/IMDB/IMDB-Movie-Data.csv")
1.2 缺失值的处理逻辑
对于NaN的数据,在numpy中我们是如何处理的?在pandas中我们处理起来非常容易

判断数据是否为NaN:pd.isnull(df),pd.notnull(df)
处理方式:

存在缺失值nan,并且是np.nan:
1、删除存在缺失值的:dropna(axis=‘rows’)
2、替换缺失值:fillna(df[].mean(), inplace=True)
不是缺失值nan,有默认标记的
1.3 存在缺失值nan,并且是np.nan
删除

pandas删除缺失值,使用dropna的前提是,缺失值的类型必须是np.nan

movie.dropna()
替换缺失值

替换存在缺失值的样本

替换? 填充平均值,中位数

movie[‘Revenue (Millions)’].fillna(movie[‘Revenue (Millions)’].mean(), inplace=True)

movie[‘Metascore’].fillna(movie[‘Metascore’].mean(), inplace=True)
1.4 不是缺失值nan,有默认标记的
数据是这样的:

问号缺失值

wis = pd.read_csv(“https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data”)
处理思路分析:

1、先替换‘?’为np.nan

df.replace(to_replace=, value=)

2、在进行缺失值的处理

把一些其它值标记的缺失值,替换成np.nan

wis = wis.replace(to_replace=’?’, value=np.nan)

wis.dropna()
高级处理-数据离散化
学习目标
目标
应用cut、qcut实现数据的区间分组
应用get_dummies实现数据的哑变量矩阵
应用
找出股票的涨跌幅异动(异常)值
1、为什么要离散化(了解)
连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。离散化方法经常作为数据挖掘的工具。

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

离散化有很多种方法,这使用一种最简单的方式去操作

原始人的身高数据:165,174,160,180,159,163,192,184
假设按照身高分几个区间段:150~165, 165180,180195
这样我们将数据分到了三个区间段,我可以对应的标记为矮、中、高三个类别,最终要处理成一个"哑变量"矩阵

哑变量矩阵

3、股票的涨跌幅离散化
3.1验证涨跌幅变化是否符合正态分布
涨跌幅正态分布显示

发现基本符合,但是有肥尾现象

data = pd.read_csv("./data/stock_day/stock_day.csv")
p_change= data[‘p_change’]
p_change.hist(bins=80)
plt.show()
3.2 将股票涨跌幅数据进行分组
股票涨跌幅分组

使用的工具:

pd.qcut:对数据进行分组
将数据分组 一般会与value_counts搭配使用,统计每组的个数
series.value_counts():统计分组次数

自行分组

qcut = pd.qcut(np.abs(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 股票涨跌幅分组数据变成哑变量矩阵
dummaries = pd.get_dummies(p_counts, prefix=“rise”)
哑变量矩阵

小结
数据离散化
qcut、cut实现数据分组
get_dummies实现哑变量矩阵
高级处理-合并
学习目标
目标
应用pd.concat实现数据的合并
应用pd.merge实现数据的合并
应用

如果你的数据由多张表组成,那么有时候需要将不同的内容合并在一起分析

1、pd.concat实现数据合并
pd.concat([data1, data2], axis=1)
按照行或列进行合并
比如我们将刚才处理好的哑变量与原数据合并

股票哑变量合并

pd.concat([data, dummaries], axis=1)
2、pd.merge
pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=(’_x’, ‘_y’), copy=True, indicator=False,validate=None)
可以指定按照两组数据的共同键值对合并或者左右各自
left: A DataFrame object
right: Another DataFrame object
on: Columns (names) to join on. Must be found in both the left and right DataFrame objects.
left_on=None, right_on=None:指定左右键
Merge method SQL Join Name Description
left LEFT OUTER JOIN Use keys from left frame only
right RIGHT OUTER JOIN Use keys from right frame only
outer FULL OUTER JOIN Use union of keys from both frames
inner INNER JOIN Use intersection of keys from both frames
案例: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’])
内连接

1、左连接
result = pd.merge(left, right, how=‘left’, on=[‘key1’, ‘key2’])
左连接

2、右连接
result = pd.merge(left, right, how=‘right’, on=[‘key1’, ‘key2’])
右连接

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

3、pd.join
高级处理-交叉表与透视表
学习目标
目标
应用crosstab和pivot_table实现交叉表与透视表
应用
股票的每日涨跌跟星期几关系大
1、交叉表与透视表什么作用
探究股票的涨跌与星期几有关?

以下图当中表示,week代表星期几,1,0代表这一天股票的涨跌幅是好还是坏,里面的数据代表比例

可以理解为所有时间为星期一等等的数据当中涨跌幅好坏的比例

交叉表透视表作用

crosstab

2、使用crosstab(交叉表)实现上图
交叉表:交叉表用于计算一列数据对于另外一列数据的分组个数(寻找两个列之间的关系)
pd.crosstab(value1, value2)
2.1案例分析:

准备两列数据,星期数据以及涨跌幅是好是坏数据
进行交叉表计算

寻找星期几跟股票张得的关系

1、先把对应的日期找到星期几

date = pd.to_datetime(data.index).weekday
data[‘week’] = date

2、假如把p_change按照大小去分个类0为界限

data[‘posi_neg’] = np.where(data[‘p_change’] > 0, 1, 0)

通过交叉表找寻两列数据的关系

count = pd.crosstab(data[‘week’], data[‘posi_neg’])
但是我们看到count只是每个星期日子的好坏天数,并没有得到比例,该怎么去做?

对于每个星期一等的总天数求和,运用除法运算求出比例

算数运算,先求和

count.sum(axis=1).astype(np.float32)

pro = count.div(count.sum(axis=1).astype(np.float32), axis=0)
2.2为了更好的看出效果
使用plot画出这个比例,使用一直stacked的柱状图

pro.plot(kind=‘bar’, stacked=True)
plt.show()
3、使用pivot_table(透视表)实现上述功能
使用透视表,刚才的过程更加简单

DataFrame.pivot_table([], index=[])

通过透视表,将整个过程变成更简单一些

data.pivot_table([‘posi_neg’], index=[‘week’])
小结
交叉表与透视表的作用
高级处理-分组与聚合
学习目标
目标
应用groupby和聚合函数实现数据的分组与聚合
应用
星巴克零售店数据的分组与聚合
分组与聚合通常是分析数据的一种方式,通常与一些统计函数一起使用,查看数据的分组情况

想一想其实刚才的交叉表与透视表也有分组的功能,所以算是分组的一种形式,只不过他们主要是计算次数或者计算比例!!

1、什么分组与聚合
分组聚合原理

2、通过一个例子来理解分组聚合
2.1、不同颜色的不同笔的价格数据
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]})
2.2、分组API
DataFrame.groupby(key, as_index=False)
key:分组的列数据,可以多个

分组,求平均值

col.groupby([‘color’])[‘price1’].mean()

col[‘price1’].groupby(col[‘color’]).mean()

分组,数据的结构不变

col.groupby([‘color’], as_index=False)[‘price1’].mean()
3、星巴克零售店面数据
现在我们有一组关于全球星巴克店铺的统计数据,如果我想知道美国的星巴克数量和中国的哪个多,或者我想知道中国每个省份星巴克的数量的情况,那么应该怎么办?

数据来源:https://www.kaggle.com/starbucks/store-locations/data

星巴克数据

3.1、数据获取

导入星巴克店的数据

starbucks = pd.read_csv("./data/starbucks/directory.csv")
3.2、进行分组聚合

按照国家分组,求出每个国家的星巴克零售店数量

count = starbucks.groupby([‘Country’]).count()
画图显示结果

count[‘Brand’].plot(kind=‘bar’, figsize=(20, 8))
plt.show()
星巴克数量画图

假设我们加入省市一起进行分组

设置多个索引,set_index()

starbucks.groupby([‘Country’, ‘State/Province’]).count()
国家省市分组结果

仔细观察这个结构,与我们前面讲的哪个结构类似??

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值