pandas学习笔记
作用:数据处理工具
为什么用:
-
便捷的数据处理能力
-
读取文件方便
-
封装了Matplotlib、Numpy的画图与计算
核心数据结构:
DataFrame、Series
DataFrame
既有行索引(index)又有列索引(columns)的二维数组
用法:给numpy生成的数组加行、列索引
属性:index、columns、values、shape
方法:head()、tail()
例:
生成索引
import numpy as np
import pandas as pd
# 创建一个符合正态分布的10只股票5天的涨跌幅数据
stock_change=np.random.normal(0,0.1,(10,5))
pd.DataFrame(stock_change) # 默认标签是0,1,2,3
--result--
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
0 | 0.176089 | 0.067868 | -0.054592 | 0.035652 | 0.049373 |
1 | 0.171231 | 0.135464 | -0.068358 | -0.032648 | 0.206588 |
2 | 0.020702 | 0.026435 | 0.068720 | -0.127843 | -0.010169 |
3 | -0.125924 | -0.003648 | -0.083881 | 0.098695 | 0.091250 |
4 | -0.028014 | -0.022872 | -0.021559 | 0.163746 | -0.098264 |
5 | -0.027876 | 0.152759 | 0.037098 | -0.067247 | 0.082597 |
6 | -0.113928 | 0.005389 | 0.125629 | 0.045140 | 0.057990 |
7 | 0.011209 | 0.042584 | -0.001753 | 0.065630 | 0.041757 |
8 | 0.029476 | -0.226517 | 0.018308 | -0.025780 | 0.068389 |
9 | 0.162624 | 0.186431 | -0.000043 | 0.038200 | -0.054775 |
修改默认索引
import pandas as pd
import numpy as np
stock_change=np.random.normal(0,0.1,(10,5))
stock=[f"股票{i}" for i in range(10)]
date=pd.date_range(start='20211201',periods=5,freq='B') # B是指交易日
data=pd.DataFrame(stock_change,index=stock,columns=date)
--result--
2021-12-01 2021-12-02 2021-12-03 2021-12-06 2021-12-07
股票0 -0.167888 0.010385 0.052974 0.090066 -0.104986
股票1 -0.053036 -0.120812 0.165438 -0.016448 -0.069469
股票2 0.115815 0.032033 0.156428 -0.129333 0.117504
股票3 0.124743 -0.134103 -0.114200 -0.110631 0.046856
股票4 0.021602 0.054881 0.032979 -0.038664 0.184532
股票5 0.146870 0.060889 0.020779 0.068173 0.020743
股票6 -0.189889 -0.043438 -0.096933 -0.143452 -0.002345
股票7 -0.079945 -0.004975 -0.098980 -0.265815 -0.008600
股票8 -0.018101 -0.030301 0.007139 0.087968 -0.082797
股票9 -0.038282 0.123871 -0.189982 0.023723 -0.114994
属性与方法
属性:
print(data.index) # 行索引
print(data.columns) # 列索引
print(data.values) # 列表内容(除了行列索引以外)
print(data.shape) # 形状(不包括行列索引)
data.T # 转置
---result---
Index(['股票0', '股票1', '股票2', '股票3', '股票4', '股票5', '股票6', '股票7', '股票8', '股票9'], dtype='object')
DatetimeIndex(['2021-12-01', '2021-12-02', '2021-12-03', '2021-12-06',
'2021-12-07'],
dtype='datetime64[ns]', freq='B')
array([[-0.16788752, 0.01038496, 0.05297444, 0.0900659 , -0.10498636],
[-0.05303582, -0.12081175, 0.16543809, -0.01644756, -0.06946922],
[ 0.11581523, 0.03203341, 0.15642769, -0.12933262, 0.11750376],
[ 0.12474263, -0.13410278, -0.11419986, -0.11063098, 0.04685557],
[ 0.02160158, 0.05488072, 0.03297893, -0.03866449, 0.1845319 ],
[ 0.14686969, 0.06088896, 0.02077869, 0.0681735 , 0.02074334],
[-0.18988872, -0.04343836, -0.09693315, -0.14345232, -0.00234521],
[-0.07994544, -0.00497477, -0.09898007, -0.26581541, -0.0085996 ],
[-0.01810077, -0.03030116, 0.00713854, 0.08796799, -0.08279727],
[-0.03828196, 0.12387088, -0.1899818 , 0.02372315, -0.11499372]])
(10, 5)
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-01 -0.167888 -0.053036 0.115815 0.124743 0.021602 0.146870 -0.189889 -0.079945 -0.018101 -0.038282
2021-12-02 0.010385 -0.120812 0.032033 -0.134103 0.054881 0.060889 -0.043438 -0.004975 -0.030301 0.123871
2021-12-03 0.052974 0.165438 0.156428 -0.114200 0.032979 0.020779 -0.096933 -0.098980 0.007139 -0.189982
2021-12-06 0.090066 -0.016448 -0.129333 -0.110631 -0.038664 0.068173 -0.143452 -0.265815 0.087968 0.023723
2021-12-07 -0.104986 -0.069469 0.117504 0.046856 0.184532 0.020743 -0.002345 -0.008600 -0.082797 -0.114994
方法:
data.head(3) #默认显示前五行,目前显示前三行
data.tail(2) #显示后五行
索引设置
- 修改行列索引值
- 重设索引
- 以某列值设置新索引
# 1、修改行列索引值
# 不能单独修改某一个索引,只能整体修改
stock_=[f'股票_{i}' for i in range(10)]
data.index=stock_
print(data)
# 2、重设索引
data.reset_index(drop=False) # drop=True把之前的索引删除
--result--
index | 2021-12-01 00:00:00 | 2021-12-02 00:00:00 | 2021-12-03 00:00:00 | 2021-12-06 00:00:00 | 2021-12-07 00:00:00 | |
---|---|---|---|---|---|---|
0 | 股票_0 | -0.167888 | 0.010385 | 0.052974 | 0.090066 | -0.104986 |
1 | 股票_1 | -0.053036 | -0.120812 | 0.165438 | -0.016448 | -0.069469 |
2 | 股票_2 | 0.115815 | 0.032033 | 0.156428 | -0.129333 | 0.117504 |
3 | 股票_3 | 0.124743 | -0.134103 | -0.114200 | -0.110631 | 0.046856 |
4 | 股票_4 | 0.021602 | 0.054881 | 0.032979 | -0.038664 | 0.184532 |
5 | 股票_5 | 0.146870 | 0.060889 | 0.020779 | 0.068173 | 0.020743 |
6 | 股票_6 | -0.189889 | -0.043438 | -0.096933 | -0.143452 | -0.002345 |
7 | 股票_7 | -0.079945 | -0.004975 | -0.098980 | -0.265815 | -0.008600 |
8 | 股票_8 | -0.018101 | -0.030301 | 0.007139 | 0.087968 | -0.082797 |
9 | 股票_9 | -0.038282 | 0.123871 | -0.189982 | 0.023723 | -0.114994 |
# 3、以某列值设置新索引
# 生成新df
df=pd.DataFrame({'month':[1,4,7,10],
'year':[2012,2014,2013,2014],
'sale':[55,84,66,24]}
)
--result--
month | year | sale | |
---|---|---|---|
0 | 1 | 2012 | 55 |
1 | 4 | 2014 | 84 |
2 | 7 | 2013 | 66 |
3 | 10 | 2014 | 24 |
# 以year设置新索引
df.set_index('year',drop=True)
--result--
month sale
year
2012 1 55
2014 4 84
2013 7 66
2014 10 24
# 设置多个索引
new_df=df.set_index(['year','month'])
Series
带索引的一维数组(只有行索引)
属性:
- index
- values
创建Series
# 1、指定索引
pd.Series([1,2,3,4,5,6],index=['a','b','c','d','e','f'])
--result--
a 1
b 2
c 3
d 4
e 5
f 6
dtype: int64
# 2、通过字典数据创建
pd.Series({'red':100,'blue':200,'green':800})
--result--
red 100
blue 200
green 800
dtype: int64
基本数据操作
索引操作
- 直接索引
- loc使用索引,按名字索引
- iloc使用索引,按数字索引
import pandas as pd
# data=pd.read_csv('./stock_day.csv')
#丢弃一些不需要的列
# data=data.drop(['ma5','ma10'],axis=1)
df=pd.DataFrame({'month':[1,4,7,10],
'year':[2012,2014,2013,2014],
'sale':[55,84,66,24]}
)
--result--
month year sale
0 1 2012 55
1 4 2014 84
2 7 2013 66
3 10 2014 24
# 1、直接索引
# 当查询某一列时,df[]传入一个columns值。
df['month']
# 当查询多列时,df[]传入一个columns值的列表。
df[['month','year']]
# 当查询一行或者多行,只能传入index值的切片。
df[0:1]
# 当查询具体某一个数,需要先列后行
df['month'][0] # 先列后行
--result--
1
# 2、loc使用索引,按名字索引
df.loc[0]['month']
--result--
1
# 3、iloc使用索引,按数字索引
df.iloc[0][0]
--result--
1
赋值操作
# 1、整列赋值
df.month=55
--result--
month year sale
0 55 2012 55
1 55 2014 84
2 55 2013 66
3 55 2014 24
# 2、给某个数赋值
df.iloc[0,0]=100
--result--
month year sale
0 100 2012 55
1 55 2014 84
2 55 2013 66
3 55 2014 24
排序操作
-
内容排序
df.sort_values(by='',ascending=)
ascending=False/True(降序/升序)
-
索引排序
df.sort_index(ascending=)
ascending=False/True(降序/升序)
排序:
# 生成数据
import pandas as pd
import numpy as np
stock_change=np.random.normal(0,0.1,(10,5))
stock=[f"股票{i}" for i in range(10)]
date=pd.date_range(start='20211201',periods=5,freq='B') # B是指交易日
data=pd.DataFrame(stock_change,index=stock,columns=date).T
print(data)
--result--
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-01 -0.041013 -0.013067 -0.045232 -0.038931 0.033832 -0.154677 0.044751 -0.155891 -0.069329 -0.100410
2021-12-02 0.145314 -0.253627 -0.068423 0.063953 0.095960 -0.109584 -0.073027 -0.118005 0.036249 0.068408
2021-12-03 0.135547 0.060643 -0.071535 0.067036 -0.064006 -0.111672 0.058225 0.102011 0.089775 -0.088339
2021-12-06 0.059400 -0.094440 0.088875 0.160057 -0.003398 -0.081026 -0.066847 -0.036730 0.046122 -0.130619
2021-12-07 0.059348 -0.218644 -0.090170 0.034526 0.116252 -0.010645 -0.146290 0.053854 -0.079973 -0.081551
# 索引排序
data.sort_index(ascending=False)
--result--
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-07 0.059348 -0.218644 -0.090170 0.034526 0.116252 -0.010645 -0.146290 0.053854 -0.079973 -0.081551
2021-12-06 0.059400 -0.094440 0.088875 0.160057 -0.003398 -0.081026 -0.066847 -0.036730 0.046122 -0.130619
2021-12-03 0.135547 0.060643 -0.071535 0.067036 -0.064006 -0.111672 0.058225 0.102011 0.089775 -0.088339
2021-12-02 0.145314 -0.253627 -0.068423 0.063953 0.095960 -0.109584 -0.073027 -0.118005 0.036249 0.068408
2021-12-01 -0.041013 -0.013067 -0.045232 -0.038931 0.033832 -0.154677 0.044751 -0.155891 -0.069329 -0.100410
# 内容排序
data.sort_values(by='股票0',ascending=False)
--result--
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-02 0.145314 -0.253627 -0.068423 0.063953 0.095960 -0.109584 -0.073027 -0.118005 0.036249 0.068408
2021-12-03 0.135547 0.060643 -0.071535 0.067036 -0.064006 -0.111672 0.058225 0.102011 0.089775 -0.088339
2021-12-06 0.059400 -0.094440 0.088875 0.160057 -0.003398 -0.081026 -0.066847 -0.036730 0.046122 -0.130619
2021-12-07 0.059348 -0.218644 -0.090170 0.034526 0.116252 -0.010645 -0.146290 0.053854 -0.079973 -0.081551
2021-12-01 -0.041013 -0.013067 -0.045232 -0.038931 0.033832 -0.154677 0.044751 -0.155891 -0.069329 -0.100410
DataFrame运算
1、算数运算
和numpy类似即可
# 两种形式都可以,1、用加减运算符 2、用命令
# 股票0所在列减3
data['股票0'].sub(3)
data['股票0']-3
# 股票0所在列加1
data['股票0'].add(1)
data['股票0']+1
2、逻辑运算
- 逻辑运算符
- 逻辑运算函数
# 1、逻辑运算符: < > | &
# 和numpy类似
data[data['股票0']>0]
--result--
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-01 0.158967 -0.085940 0.027440 -0.023698 -0.088432 0.015080 -0.061509 0.153487 0.021066 0.003014
2021-12-02 0.195885 0.100498 -0.032846 0.029141 -0.029607 -0.035054 -0.058683 -0.080404 -0.034530 -0.060497
2021-12-07 0.036149 0.089611 -0.114616 0.077120 -0.031470 0.090487 -0.202558 -0.342146 0.114724 0.002734
data[(data['股票0']>0)&(data['股票1']>0)]
--result--
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
2021-12-02 0.195885 0.100498 -0.032846 0.029141 -0.029607 -0.035054 -0.058683 -0.080404 -0.034530 -0.060497
2021-12-07 0.036149 0.089611 -0.114616 0.077120 -0.031470 0.090487 -0.202558 -0.342146 0.114724 0.002734
# 2、逻辑运算函数:data.query data.isin([3,2,1])
data.query('股票0>0&股票1>0') #索引和上边作用一样
data.iloc[0:5,0:3].isin([3,2,1]) #dataframe第0行到第4行,第0列到第2列中是否有3,2,1
---result---
股票0 股票1 股票2
2021-12-01 False False False
2021-12-02 False False False
2021-12-03 False False False
2021-12-06 False False False
2021-12-07 False False False
3、统计运算
-
和numpy一样的统计指标(没有argmax)。
-
data.describe()的含义:综合分析,可以得出多个统计结果
-
data.idxmax(axis=0): 最大值位置
-
累计统计函数
cumsum 计算前1/2/3/…/n个数的和
cummax 计算前1/2/3/…/n个数的最大值
cummin 计算前1/2/3/…/n个数的最小值
cumprod 计算前1/2/3/…/n个数的积
# 比numpy多一个 data.describe()
data.describe()
---result---
股票0 股票1 股票2 股票3 股票4 股票5 股票6 股票7 股票8 股票9
count 5.000000 5.000000 5.000000 5.000000 5.000000 5.000000 5.000000 5.000000 5.000000 5.000000
mean 0.052936 0.036970 -0.029906 0.040171 0.009361 0.011691 -0.052978 -0.036160 0.019197 -0.007515
std 0.126726 0.079518 0.112368 0.039694 0.086298 0.066257 0.109435 0.191808 0.074329 0.065947
min -0.114749 -0.085940 -0.155420 -0.023698 -0.088432 -0.071323 -0.202558 -0.342146 -0.070203 -0.074644
25% -0.011571 -0.000623 -0.114616 0.029141 -0.031470 -0.035054 -0.061509 -0.080404 -0.034530 -0.060497
50% 0.036149 0.081302 -0.032846 0.056291 -0.029607 0.015080 -0.058683 0.007277 0.021066 0.002734
75% 0.158967 0.089611 0.027440 0.061999 0.072940 0.059263 -0.048551 0.080986 0.064930 0.003014
max 0.195885 0.100498 0.125913 0.077120 0.123372 0.090487 0.106411 0.153487 0.114724 0.091817
data.idxmax(axis=0)
--result--
股票0 2021-12-02
股票1 2021-12-02
股票2 2021-12-06
股票3 2021-12-07
股票4 2021-12-06
股票5 2021-12-07
股票6 2021-12-06
股票7 2021-12-01
股票8 2021-12-07
股票9 2021-12-06
data['股票0']
--result-
2021-12-01 0.158967
2021-12-02 0.195885
2021-12-03 -0.011571
2021-12-06 -0.114749
2021-12-07 0.036149
Freq: B, Name: 股票0, dtype: float64
data['股票0'].cumsum()
--result-
2021-12-01 0.158967
2021-12-02 0.354852
2021-12-03 0.343281
2021-12-06 0.228532
2021-12-07 0.264681
Freq: B, Name: 股票0, dtype: float64
内置画图
data['股票0'].cumsum.plot()
可以看到股票前五工作日走势
4、自定义运算
apply(func,axis=0)
func:自定义函数
axis=0:默认按列运算,axis=1:默认按行运算
data.apply(lambda x: x.max()-x.min())
pandas绘图
- DataFrame.plot(x=None,y=None,king=‘line’)
data.plot(x="volume", y="turnover", kind="scatter")
data.plot(x="high", y="low", kind="scatter")
- Series.plot
sr.plot(kind='line')
文件的读取与存储
1. CSV(文本最多)
-
读取文件
-
pd.read_csv(path,usecols=[],names=[])
usecols:直接提取想要的列
names:加列名
# 1、读想要的列
data=pd.read_csv('./1.csv',usecols=["high", "low", "open", "close"]) # 读那些列
# 2、如果列没有列名,用names传入,给图表加列名
data=pd.read_csv('./2.csv',names=[ "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"])
-
-
保存文件
-
dataframe.to_csv(path,columns=[‘股票0’], index=False)
-
保存opend列数据,index=False不要行索引
-
# 都是保存前5行,第0列,效果一样
data.iloc[:,0].to_csv('test.csv',index=False)
data[0:5].to_csv('1.csv',columns=['股票0'],index=False)
2. HDF5(可以存储3维数据)
-
hdf5文件读取和存储时需要指定一个键(类似matlab的变量名),值为要读取的DataFrame
-
data=pd.read_hdf(路径,key='') df.to_hdf('',key='')
-
data=pd.read_hdf('./1.h5',key='2')
data.to_hdf('test.h5',key='2')
3. JSON
-
df=pd.read_json('1.json',orient='records',lines=True) df.to_json('1.json',orient='records',lines=True)
-
orient:预期的json字符串格式,一般是records
-
lines:按照每行读取json文件
sa = pd.read_json("Sarcasm_Headlines_Dataset.json", orient="records", lines=True)
sa.to_json("test.json", orient="records", lines=True)