需求:创建一个符合正态分布的10个股票5天的涨跌幅数据,使用 NumPy
创建示例代码如下:
import numpy as np
stock_change = np.random.normal(0, 1, size=(10,5))
stock_change
上述代码执行结果如下:
上述结果,很难看出来这个数据是用来描述什么的,并且数据结构也不是十分的清晰。使用 Pandas
创建示例代码如下:
import pandas as pd
import numpy as np
stock_change = np.random.normal(0, 1, size=(10,5))
# 1.构造行索引列表
stock_code = ["股票{}".format(str(i+1)) for i in range(stock_change2.shape[0])]
# 2.生成一个时间的序列 为列索引
# start: "2020-05-01" 开始时间
# end: 结束日期
# periods: 时间天数 stock_change2.shape[1]==> 5天
# freq: 递进单位,默认1天,'B'默认略过周末
# 注意: end和periods使用一个就可以了
stock_time = pd.date_range("2020-05-01", periods=stock_change2.shape[1], freq="B")
pd.DataFrame(stock_change, index=stock_code, columns=stock_time)
上述代码执行结果如下:
从执行结果来看Pandas
让数据更有意义的显示。Pandas
学习的目的如下:
DataFrame对象既有行索引,又有列索引:
转置,如下:
head():如果不补充参数,默认5行。填入参数N则显示前N行,如下:
tail() 如果不补充参数,默认5行。填入参数N则显示后N行,示例代码如下:
修改行列索引值,示例代码如下:
reset_index(drop=False),设置新的下标索引,drop: 默认为False,不删除原来索引,如果为True,删除原来的索引值。示例代码如下:
以某列值设置为新的索引,set_index(keys, drop=True)
打印刚才的df的行索引结果:
多级或分层索引对象。index属性:
什么是Series结构呢,我们直接看下面的图:
series结构只有行索引。我们将之前的涨跌幅数据进行转置,然后获取股票 __0
的所有数据,示例代码如下:
为了更好的理解这些基本操作,我们将读取一个真实的股票数据。关于文件操作,后面在介绍,这里只先用一下API,文件的获取路径如下:
链接:https://pan.baidu.com/s/1-3LnQSHyYeeFSEJ6roDY2w 密码:40tm
读取文件操作如下:
import pandas as pd
# 1.读取文件
data = pd.read_csv("./data/stock_day.csv")
# 2.删除一些列,让数据更简单些,再去做后面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
在 此处 我们已经学习过使用索引选取序列和切片选择,Pandas
也支持类似的操作,也可以直接使用列名、行名称,甚至组合使用。
获取2018-02-14
这天的 open
的结果,示例代码如下:
data["open"]["2018-02-14"] # 先列后行 21.49
获取从 2018-02-27 : 2018-02-14
,high
的结果,示例代码如下:
# 获取从'2018-02-27':'2018-02-14','high'的结果
data.loc['2018-02-27':'2018-02-14', "high"] # 使用loc:只能指定行列索引的名字
上述代码执行结果为:
获取前10天数据的 open
和 high
列的结果,示例代码如下:
data.iloc[:10, :2] # 使用iloc可以通过索引的下标去获取
获取行第1天到第4天,open/high/close
这三个指标的结果,示例代码如下:
data.loc[data.index[:4], ["open","high","close"]]
上述代码执行结果为:
获取行第2天到第5天,open/high/close/low
这四个指标的结果,示例代码如下:
data.iloc[2:6, data.columns.get_indexer(["open","high","close","low"])]
对DataFrame当中的 open
列进行重新赋值为10
,示例代码如下:
data["open"] = 10
上述代码执行结果为:
对DataFrame当中的 open
列进行重新赋值为100
,示例代码如下:
data.open = 100
排序有两种形式,一种对于 索引
进行排序,一种对于 内容
进行排序。使用 df.sort_values(by=, ascending=),单个键排序,示例代码如下:
# 按照涨跌幅大小进行排序 , 使用ascending指定按照大小排序
data.sort_values(by="p_change").head() # 默认升序
# 按照high进行排序,如果high值相同则比较close值
# ascending=True升序 =False降序
data.sort_values(by=["high", "close"], ascending=False).head()
上述代码执行结果为:
使用 df.sort_index
给索引进行排序,这个股票的日期索引原来是从大到小,现在重新排序,从小到大,示例代码如下:
data.sort_index().head(3)
上述代码执行结果为:
使用 series.sort_values(ascending=True)
进行排序,series排序时,只有一列,不需要参数,示例代码如下:
# 对high这一列的数据进行排序
# ascending=False: 降序排列
# data["high"] 返回的就是series
data["high"].sort_values(ascending=False).head()
上述代码执行结果为:
使用 series.sort_index()
进行排序,与df一致,示例代码如下:
# 对high这一列的数据进行排序
data["high"].sort_index(ascending=True).head()
为了更好的理解这些基本操作,我们和上面一样读取一个真实的股票数据。关于文件操作,后面在介绍,这里只先用一下API,文件的获取路径如下:
链接:https://pan.baidu.com/s/1-3LnQSHyYeeFSEJ6roDY2w 密码:40tm
读取文件操作如下:
import pandas as pd
# 1.读取文件
data = pd.read_csv("./data/stock_day.csv")
# 2.删除一些列,让数据更简单些,再去做后面的操作
data = data.drop(["ma5","ma10","ma20","v_ma5","v_ma10","v_ma20"], axis=1)
add(other):比如进行数学运算加上具体的一个数字,示例代码如下:
# 给open这一列的数据都加上10
data["open"].add(10).head()
# 或者是下面这种直接相加的方式 一般使用的比较少
data["open"] + 10
上述代码执行结果为:
sub(other):比如进行数学运算减去具体的一个数字,示例代码如下:
data["open"].sub(10).head() # ==> data["open"] - 10
上述代码执行结果为:
如果想要得到每天的涨跌大小? 求出每天 close-open
价格差,示例代码如下:
data["close"].sub(data["open"]).head() # 收盘价-开盘价
例如筛选 p_change > 2
的日期数据,示例代码如下:
(data["p_change"] > 2).head() # 返回逻辑值
(data[data["p_change"]>2]).head() # 逻辑判断的结果也可以作为筛选的依据
上述代码执行结果为:
完成多个逻辑判断, 筛选 p_change > 2
并且 open > 15
,示例代码如下:
((data["p_change"] > 2) & (data["open"] > 15)).head(5)
data[(data["p_change"] > 2) & (data["open"] > 15)].head(5)
query(expr):expr指的是查询字符串。通过 query
使得刚才的过程更加方便简单。示例代码如下:
data.query("p_change>2 & open > 15").head()
上述代码执行结果为:
isin(values):例如判断 turnover
是否为4.19
,2.39
,示例代码如下:
data["turnover"].isin([4.19, 2.39]).head() # 返回逻辑值
data[data["turnover"].isin([4.19, 2.39])].head() # 返回符合条件的数据
describe():综合分析,能够直接得出很多统计结果 count/mean/std/min/max等。示例代码如下:
data.describe()
上述代码执行结果为:
统计函数在 这里 已经详细介绍,以下演示 min(最小值),max(最大值),mean(平均值),median(中位数),var(方差),std(标准差),mode(众数)的结果,示例代码如下:
data.max() # 最大值
data.min() # 最小值
data.std(0) # 标准差
data.var() # 方差
# median(): 中位数
# 中位数为将数据从小到大排列,在最中间的那个数为中位数。如果没有中间数,取中间两个数的平均值。
df = pd.DataFrame({'COL1' : [2,3,4,5,4,2],
'COL2' : [0,1,2,3,4,2]})
df.median() # [2,3,4,5,4,2]==>[2,2,3,4,4,5]==>3+4/2==>3.5
data.idxmax() # 求出最大值的位置
data.idxmin() # 求出最小值的位置
注意:对于单个函数去进行统计的时候,坐标轴还是按照这些默认为 columns
(axis=0, default),如果要对行 index
需要指定(axis=1)。
函数 | 作用 |
---|---|
cumsum | 计算前1/2/3/…/n个数的和 |
cummax | 计算前1/2/3/…/n个数的最大值 |
cummin | 计算前1/2/3/…/n个数的最小值 |
cumprod | 计算前1/2/3/…/n个数的积 |
那么这些累计统计函数怎么用?以上这些函数可以对 series
和 dataframe
操作。这里我们按照时间的从前往后来进行累计,示例代码如下:
# 排序之后,进行累计求和
data = data.sort_index()
# 对p_change进行求和
stock_rise = data["p_change"]
stock_rise.cumsum()
上述代码执行结果为:
那么如何让这个连续求和的结果更好的显示呢?
apply(func, axis=0)
定义一个 对列 最大值-最小值
的函数,示例代码如下:
data[["open", "close"]].apply(lambda x: x.max()-x.min(), axis=0)
语法格式如下:
DataFrame.plot(x=None, y=None, kind="line")
参数说明如下:
之前在 此处 已经详细讲解过上述常用的图形,这里的话不再详细的用案例进行说明,在后续代码中用到的时候在具体进行展示。
我们的数据大部分存在于文件当中,所以 Pandas
会支持复杂的IO操作,Pandas
的API支持众多的文件格式,如CSV、SQL、XLS、JSON、HDF5等。
语法格式如下:
pd.read_csv(filepath_or_buffer, sep ="," )
参数说明如下:
读取之前的股票的数据,示例代码如下:
data = pd.read_csv("./data/stock_day.csv").head() # 读取全部
# 读取文件,并且指定只获取"open", "close"指标
data = pd.read_csv("./data/stock_day.csv", usecols=["open", "close"]).head()
语法格式如下:
DataFrame.to_csv(path_or_buf=None, sep=", ",columns=None,
header=True, index=True, mode="w", encoding=None)
参数说明如下:
,
w
重写,a
追加保存 open
列的数据到csv文件中,示例代码如下:
data[:10].to_csv("./data/amo.csv", columns=["open"])
上述代码执行结果为:
会发现将索引存入到文件当中,变成单独的一列数据。如果需要删除,可以指定index参数,删除原来的文件,重新保存一次。示例代码如下:
# index: 存储不会将索引值变成一列数据
data[:10].to_csv("./data/amo2.csv", columns=["open"], index=False)
HDF5文件
的读取和存储需要指定一个键,值为要存储的DataFrame。从 h5
文件当中读取数据,语法格式如下:
pandas.read_hdf(path_or_buf,key =None,** kwargs)
参数说明如下:
DataFrame.to_hdf(path_or_buf, key, \kwargs)
示例代码如下:
# 读取文件
day_eps_ttm = pd.read_hdf("./data/stock_data/day/day_eps_ttm.h5")
# 存储文件
# 这个文件不能像csv一样 直接打开观看 只有先读取出来在观看
day_eps_ttm.to_hdf("./data/amo.h5", key="day_eps_ttm")
# 再次读取的时候,需要指定键的名字
new_eps = pd.read_hdf("./data/amo.h5", key="day_eps_ttm")
new_eps.head()
JSON是我们常用的一种数据交换格式,在前后端的交互,爬取数据的时候经常用到,也会在存储的时候选择这种格式。所以我们需要知道 Pandas
如何进行读取和存储JSON格式。
将JSON格式准换成默认的Pandas DataFrame格式,语法格式如下:
pandas.read_json(path_or_buf=None, orient=None, typ="frame", lines=False)
这里使用一个新闻标题讽刺数据集,格式为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 sues 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 catches up to our thorny political mood, for better and worse", "is_sarcastic": 0}
读取,orient
指定存储的json格式,lines
指定按照行去变成一个样本,示例代码如下:
# orient指定存储的json格式,lines指定按照行去变成一个样本
json_read = pd.read_json("./data/Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
json_read
将Pandas 对象存储为json格式,语法格式为:
DataFrame.to_json(path_or_buf=None, orient=None, lines=False)
示例代码如下:
# 存储文件
json_read.to_json("./data/amo.json", orient="records")
# 修改lines参数为True
json_read.to_json("./data/amo2.json", orient="records", lines=True)
结果为:
优先选择使用 HDF5
文件存储,有以下原因:
HDF5
在存储的时候支持压缩,使用的方式是 blosc
,这个是速度最快的也是Pandas
默认支持的HDF5
还是跨平台的,可以轻松迁移到hadoop上面笔者这篇博文写完之后脑袋都炸掉了,Pandas
高级部分的操作会在 Python数据挖掘基础(四):Pandas高级处理 中展示给大家,这篇博文太长,内容也比较多,并且在几个小时内完成,难免出现错误,希望大家多多指教,编写不易,大家手留余香,感谢。