pandas——数据移位、数据转换、数据合并、数据导出和日期数据的处理,时间序列等

pandas统计分析(下)

本文主要介绍使用pandas进行数据移位、数据转换、数据合并、数据导出和日期数据的处理,时间序列等。

数据移位

数据移位就是在分析数据时,需要移动到上一条,在pandas中,可以使用shift方法获得上一条数据。

shift(periods=1, freq=None, axis=0, fill_value=<object object at 0x0000022BE4AA85E0>)

参数:

  • periods:表示移动的幅度,可正可负,默认为1。1表示移动一次。这里移动的都是数据,索引不移动,移动之后没有对应值的,赋值为NaN。
  • freq:可选参数,默认为None,只适用于时间序列,如果这个参数存在,那么会按照参数值移动时间索引,而数据值没有发生变化。
  • axis:axis = 1表示行,axis = 0表示列。默认为0
import pandas as pd
data =[110,105,99,120,115]
index = [1,2,3,4,5]
df = pd.DataFrame(data = data,index = index,columns=['英语'])
df['升降'] = df['英语']-df['英语'].shift()
print(df)
   英语  升降
1   110   NaN
2   105  -5.0
3    99  -6.0
4   120  21.0
5   115  -5.0

数据转换

数据转换包括一列数据转多行数据、行列转换、DataFrame转字典,DataFrame转列表,DataFrame转元组

一列数据转多列数据

split方法

pandas中的DataFrame对象中的str.split方法可以实现分割字符串

split(pat=None, n=-1, expand=False)

参数:

  • pat:字符串、符合或正则表达式,字符串分割的依据,默认以空格分割字符串
  • n:整型,分割次数,默认值是-1,0或1都将返回所有拆分
  • expand:布尔型,分割后的结果是否转为DataFrame,默认值是False
  • 返回值:系列、索引、DataFrame或多重索引。
import pandas as pd
#导入excel文件指定列数据(‘买家会员名’,‘收货地址’)
df = pd.read_excel('MR/Code/04/26/mrbooks.xls',usecols=['买家会员名','收货地址'])
#使用Split方法分割收货地址
series = df['收货地址'].str.split(' ',expand=True)
df['省'] = series[0]
df['市'] = series[1]
df['区'] = series[2]
df1 = df.head()
买家会员名收货地址
0mr00001重庆 重庆市 南岸区重庆重庆市南岸区
1mr00003江苏省 苏州市 吴江区 吴江经济技术开发区亨通路江苏省苏州市吴江区
2mr00004江苏省 苏州市 园区 苏州市工业园区唯亭镇阳澄湖大道维纳阳光花园…江苏省苏州市园区
3mr00002重庆 重庆市 南岸区 长生桥镇茶园新区长电路11112号重庆重庆市南岸区
4mr00005安徽省 滁州市 明光市 三界镇中心街10001号安徽省滁州市明光市
join方法和split方法结合
df = pd.read_excel('MR/Code/04/26/mrbooks.xls',usecols=['买家会员名','宝贝标题'])

df = df.join(df['宝贝标题'].str.split(',',expand=True))
df

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YiykdvDV-1650707196634)(C:\Users\85289\AppData\Roaming\Typora\typora-user-images\image-20220420171419643.png)]

对元组数据进行分割
import pandas as pd
df = pd.DataFrame({'a':[1,2,3,4,5],'b':[(1,2),(3,4),(5,6),(7,8),(9,10)]})
print(df)
   a        b
0  1   (1, 2)
1  2   (3, 4)
2  3   (5, 6)
3  4   (7, 8)
4  5  (9, 10)
df[['b1','b2']]=df['b'].apply(pd.Series)
print(df)
df = df.join(df['b'].apply(pd.Series))
print(df)
   a        b  b1  b2
0  1   (1, 2)   1   2
1  2   (3, 4)   3   4
2  3   (5, 6)   5   6
3  4   (7, 8)   7   8
4  5  (9, 10)   9  10
   a        b  b1  b2  0   1
0  1   (1, 2)   1   2  1   2
1  2   (3, 4)   3   4  3   4
2  3   (5, 6)   5   6  5   6
3  4   (7, 8)   7   8  7   8
4  5  (9, 10)   9  10  9  10

行列转换

使用stack和unstack及pivot方法进行行列转换或重排。

stack方法是将原来的列索引转换成最内层的行索引,unstack是将最内层的行索引转换成列索引

import pandas as pd
df=pd.read_excel('MR/Code/04/29/grade.xls')
pd.set_option('display.unicode.east_asian_width',True)
df = df.set_index(['班级','序号'])# 设置2级索引‘班级’和‘序号’
df.stack()
print(df)
            姓名  得分  排名
班级 序号                   
1班  1     王*亮    84    11
     2      杨**    82    17
     3     王*彬    78    37
2班  4     赛*琪    77    51
     5      刘**    76    64
     6     刘*彤    74    89
3班  7     张*扬    72   115
     8      尹**    72   115
     9     李*旸    72   115
4班  10    *华煦    72   115
     11    于*明    72   115
     12    袁*皓    70   151
5班  13      姜*    70   151
     14     窦**    68   195
     15    张*昕    68   195

pivot方法针对列的值,指定某列的值作为行索引,指定某列的值作为列索引,然后再指定哪些列作为索引对应的值。

pivot(index=None, columns=None, values=None)
df = pd.read_excel('MR/Code/04/31/grade.xls',sheet_name= '英语3')
df1 = df.pivot(index = '序号',columns='班级',values='得分')
df1
班级1班2班3班4班5班
序号
18477727270
28276727268
37874727068

DataFrame转换为字典

使用to_dict方法,以索引作为字典的键,列作为字典的值。

import pandas as pd
df = pd.read_excel('MR/Code/04/32/mrbooks.xls')
df1 = df.groupby(['宝贝标题'])['宝贝总数量'].sum().head()
mydict = df1.to_dict()
for i,j in mydict.items():
    print(i,':\t',j)
ASP.NET项目开发实战入门全彩版 :	 32
ASP.NET项目开发实战入门全彩版,ASP.NET全能速查宝典 :	 2
Android学习黄金组合套装 :	 4
Android项目开发实战入门 :	 1
C#+ASP.NET项目开发实战入门全彩版 :	 1

DataFrame转列表

使用tolist转换

import pandas as pd
df = pd.read_excel('MR/Code/04/33/mrbooks.xls')
df1 = df[['买家会员名']].head()
list1 = df1['买家会员名'].values.tolist()
for s in list1:
    print(s)
mr00001
mr00003
mr00004
mr00002
mr00005

DataFrame转元组

先通过循环语句按行读取DataFrame数据,然后使用元组函数tuple()将其转换为元组

import pandas as pd
df = pd.read_excel('MR/Code/04/34/fl4.xls')
df1 = df[['label1','label2']].head()
tuples = [tuple(x) for x in df1.values]
for t in tuples:
    print(t)
('超巨星', '暗夜比夜星')
('黑矮星', '暗夜比夜星')
('灭霸', '暗夜比夜星')
('亡刃将军', '暗夜比夜星')
('乌木喉', '暗夜比夜星')

excel转换为html网页格式

使用to_html文件转换

import pandas as pd
df = pd.read_excel('MR/Code/04/35/mrbooks.xls')
df.to_html('mrbook.html',header=True,index = False)

数据合并

数据合并主要使用merge和concat方法

merge方法

merge是将两个DataFrame对象列名相同的列进行连接合并,两个DataFrame对象必须具有同名的列。

merge(left, right, how: str = 'inner', on=None, left_on=None, right_on=None, left_index: bool = False, right_index: bool = False, sort: bool = False, suffixes=('_x', '_y'), copy: bool = True, indicator: bool = False, validate=None)

参数说明:

  • right:合并对象

  • how:合并类型,可以是left、right、outer或inner,默认为inner

    • left:只使用来自左数据集的键,类似于sql左外部联接,保留键的顺序
    • right:只使用来自右数据集的键,类似于sql右外部联接,保留键的顺序
    • outer:使用来自两个数据集的键,类似于sql外部连接,按字典顺序对键进行排序
    • inner:使用来自两个数据集的键的交集,类似于sql内部连接,保持左键的顺序
  • on:标签、列表、数组,默认为None,DataFrame对象连接的列或索引级别名称

  • left_on:要连接的左数据集的列或索引级名称

  • right_on:要连接的右数据集的列

  • left_index:布尔型,使用左数据集的索引作为连接键。如果是多重索引,则其他数据中的键数(索引或列数)必须匹配索引级别数

  • right_index:布尔型,使用右数据集的索引作为连接键

  • sort:在合并结果中按照字典顺序对连接键进行排序

  • suffixes:当左侧数据集和右侧数据集的列名相同时,数据合并后列名将带上’_x’和’_y’后缀

  • copy:是否复制数据,默认为True

  • indicator:布尔型或字符串,默认为false

  • validate:字符串,检查合并数据是否为指定类型。

    • one_to_one或“1:1”:检查合并键在左右数据集中是否都是唯一的
    • one_to_many或“1:m”:检查合并键在左数据集中是否都是唯一的
    • many_to_one或“m:1”:检查合并键在右数据集中是否都是唯一的
    • many_to_many或“m:m”:允许但不检查
  • 返回值:DataFrame对象,两个合并对象的数据集

    常规合并
    import pandas as pd
    df1 =pd.DataFrame({'编号':['mr001','mr002','mr003'],
                      '语文':[110,105,109],
                      '数学':[105,88,120],
                      '英语':[99,115,130]})
    df2 = pd.DataFrame({'编号':['mr001','mr002','mr003'],
                       '体育':[34.5,39.7,38]})
    df_merge = pd.merge(df1,df2,on = '编号')
    print(df_merge)
    
        编号  语文  数学  英语  体育
    0  mr001   110   105    99  34.5
    1  mr002   105    88   115  39.7
    2  mr003   109   120   130  38.0
    
df_merge = pd.merge(df1,df2,right_index=True,left_index=True)
print(df_merge)

  编号_x  语文  数学  英语 编号_y  体育
0  mr001   110   105    99  mr001  34.5
1  mr002   105    88   115  mr002  39.7
2  mr003   109   120   130  mr003  38.0

df_merge = pd.merge(df1,df2,on = '编号',how = 'left')
print(df_merge)
    编号  语文  数学  英语  体育
0  mr001   110   105    99  34.5
1  mr002   105    88   115  39.7
2  mr003   109   120   130  38.0
多对一的数据合并

多对一是指两个数据集的共有列中的数据不是一对一的关系

df2 =pd.DataFrame({'编号':['mr001','mr001','mr003'],
                  '语文':[110,105,109],
                  '数学':[105,88,120],
                  '英语':[99,115,130],
                  '时间':['1月','2月','1月']})
df1 = pd.DataFrame({'编号':['mr001','mr002','mr003'],
                   '学生姓名':['a','b','c']})
df_merge = pd.merge(df1,df2,on ='编号')
print(df_merge)
    编号 学生姓名  语文  数学  英语 时间
0  mr001        a   110   105    99  1月
1  mr001        a   105    88   115  2月
2  mr003        c   109   120   130  1月
多对多的数据合并

多对多是指两个数据集的共有列中的数据不全是一对一的关系,都有重复数据。

#合并数据并相互补全
import pandas as pd

df1 = pd.DataFrame({'编号':['mr001','mr002','mr003','mr001','mr001'],
                    '体育':[34.5,39.7,38,33,35]})

df2 = pd.DataFrame({'编号':['mr001','mr002','mr003','mr003','mr003'],
                    '语文':[110,105,109,110,108],
                    '数学':[105,88,120,123,119],
                    '英语':[99,115,130,109,128]})

df_merge=pd.merge(df1,df2)
print(df_merge)
    编号  体育  语文  数学  英语
0  mr001  34.5   110   105    99
1  mr001  33.0   110   105    99
2  mr001  35.0   110   105    99
3  mr002  39.7   105    88   115
4  mr003  38.0   109   120   130
5  mr003  38.0   110   123   109
6  mr003  38.0   108   119   128

concat方法

concat(objs: Union[Iterable[ForwardRef('NDFrame')], Mapping[Union[Hashable, NoneType], ForwardRef('NDFrame')]], axis=0, join='outer', ignore_index: bool = False, keys=None, levels=None, names=None, verify_integrity: bool = False, sort: bool = False, copy: bool = True)

参数:

  • objs:Series、DataFrame或panel对象的序列或映射。如果传入一个字典,则排序的键将用作键参数
  • axis:
  • join:值为inner(内连接)或outer(外连接),处理其他轴上的索引方式。默认为outer
  • ignore_index:布尔值,默认为false,保留索引
  • keys:序列,默认为none。使用传递的键作为最外层构建层次索引。如果为多索引,应该使用元组
  • levels:序列列表,默认为none。用于构建multiindex的特定级别(唯一值);否则,他们将从键推断
  • names:list列表,默认为none,结果层次索引中的级别的名称
相同字段的表首位连接

表结构相同的数据直接合并,表首尾相接

dfs = [df1,df2,df3]
result = pd.concat(dfs)
result = pd.concat(dfs,keys = ['1月','2月','3月'])
横向表合并(行对齐)

当合并的数据列名称不一致,可以设置参数,concat()方法将按行对齐,然后将不同列名的两组数据进行合并,缺失的用NaN填充

result = pd.concat([df1,df4],axis = 1)
交叉合并

交叉合并需要在代码中加上join参数,值为inner,则为两张表的交集,为outer,则为两张表的并集。

result = pd.concat([df1,df4],axis = 1,join = 'inner')
指定表对齐数据(行对齐)

如果指定参数join_axes,就可以指定根据哪张表来对齐数据。

result = pd.concat([df1,df4],axis = 1,join_axis = [df4.index])

数据导出

导出为excel文件

使用to_excel方法

to_excel(excel_writer, sheet_name: 'str' = 'Sheet1', na_rep: 'str' = '', float_format: 'Optional[str]' = None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True, freeze_panes=None, storage_options: 'StorageOptions' = None)
df_merge.to_excel('merge.xlsx')

df1.to_excel('df1.xlsx',sheet_name='df1')

导出为csv文件

to_csv(path_or_buf: 'Optional[FilePathOrBuffer]' = None, sep: 'str' = ',', na_rep: 'str' = '', float_format: 'Optional[str]' = None, columns: 'Optional[Sequence[Label]]' = None, header: 'Union[bool_t, List[str]]' = True, index: 'bool_t' = True, index_label: 'Optional[IndexLabel]' = None, mode: 'str' = 'w', encoding: 'Optional[str]' = None, compression: 'CompressionOptions' = 'infer', quoting: 'Optional[int]' = None, quotechar: 'str' = '"', line_terminator: 'Optional[str]' = None, chunksize: 'Optional[int]' = None, date_format: 'Optional[str]' = None, doublequote: 'bool_t' = True, escapechar: 'Optional[str]' = None, decimal: 'str' = '.', errors: 'str' = 'strict', storage_options: 'StorageOptions' = None)
df.to_csv('Result.csv')

#分隔符
df.to_csv('result.csv',sep='?')

#替换空值
df.to_csv('result.csv',na_rep='NA')
#格式化数据,保留两位小数
df.to_csv('result.csv',float_format='%.2f')
# 保留某列数据,保存索引列和name列
df.to_csv('result.csv',columns=['name'])
#是否保留列名,不保留列名
df.to_csv('result.csv',header=True)
#是否保留行索引,不保留行索引
df.to_csv('result.csv',index = False)

导出多个sheet

导出多个sheet,首先使用pd.ExcelWriter方法打开一个excel文件,然后使用to_excel方法导出指定的sheet

df1.to_excel('df1.xlsx',name = 'df1')
work = pd.ExcelWriter('df2.xlsx')
df1.to_excel(work,sheet_name='df2')
df1['A'].to_excel(work,sheet_name='df3')
work.save()

日期数据处理

DataFrame的日期转换

日常工作中,日期格式的表达有很多种,我们可以通过pandas中的to_datetime方法来批量出路日期数据转换。

to_datetime(arg: Union[~DatetimeScalar, List, Tuple, ~ArrayLike, ForwardRef('Series')], errors: str = 'raise', dayfirst: bool = False, yearfirst: bool = False, utc: Union[bool, NoneType] = None, format: Union[str, NoneType] = None, exact: bool = True, unit: Union[str, NoneType] = None, infer_datetime_format: bool = False, origin='unix', cache: bool = True)
import pandas as pd
df = pd.DataFrame({'原日期':['14-Feb-20','02/14/2020',
                         '2020.02.14','20200214']})
df['转换后的日期'] = pd.to_datetime(df['原日期'])
print(df)
import pandas as pd
df = pd.DataFrame({'原日期':['14-Feb-20','02/14/2020',
                         '2020.02.14','20200214']})
df['转换后的日期'] = pd.to_datetime(df['原日期'])
print(df)
       原日期 转换后的日期
0   14-Feb-20   2020-02-14
1  02/14/2020   2020-02-14
2  2020.02.14   2020-02-14
3    20200214   2020-02-14

将一组数据组合为日期数据

import pandas as pd
df=  pd.DataFrame({'year':[2018,2019,2020],
                 'month':[1,3,2],
                 'day':[4,5,14],
                 'hour':[13,8,2],
                 'minute':[23,12,14],
                  'second':[2,4,0]}
                 )
df['组合后的日期'] = pd.to_datetime(df)
print(df)
   year  month  day  hour  minute  second        组合后的日期
0  2018      1    4    13      23       2 2018-01-04 13:23:02
1  2019      3    5     8      12       4 2019-03-05 08:12:04
2  2020      2   14     2      14       0 2020-02-14 02:14:00

dt对象的使用

dt对象是Series对象中用于获取日期属性的一个访问器对象,可以获取日期中的年、月、日、星期数、季节等,还可以判断日期是否处在年底。

Series.dt()
#获取年、月、日
df['年'],df['月'],df['日']=df['日期'].dt.year,df['日期'].dt.month,df['日期'].dt.day
#获取星期几
df['星期几']=df['日期'].dt.day_name()
#判断所处季度
df['季度']=df['日期'].dt.quarter
是否为年底最后一天
df['是否年底']=df['日期'].dt.is_year_end
import pandas as pd

df=pd.DataFrame({'原日期':['2019.1.05', '2019.2.15', '2019.3.25','2019.6.25','2019.9.15','2019.12.31']})
df['日期']=pd.to_datetime(df['原日期'])
df['年'],df['月'],df['日'] = df['日期'].dt.year,df['日期'].dt.month,df['日期'].dt.day
df['星期几'] = df['日期'].dt.day_name()
df['季度'] = df['日期'].dt.quarter
df['是否年底'] = df['日期'].dt.is_year_end
print(df)
       原日期       日期    年  月  日    星期几  季度  是否年底
0   2019.1.05 2019-01-05  2019   1   5  Saturday     1     False
1   2019.2.15 2019-02-15  2019   2  15    Friday     1     False
2   2019.3.25 2019-03-25  2019   3  25    Monday     1     False
3   2019.6.25 2019-06-25  2019   6  25   Tuesday     2     False
4   2019.9.15 2019-09-15  2019   9  15    Sunday     3     False
5  2019.12.31 2019-12-31  2019  12  31   Tuesday     4      True

获取日期区间的数据

获取日期区间的数据方法是直接在DataFrame中输入日期或日期区间,但前提是必须设置日期为索引。

import pandas as pd
df = pd.read_excel('MR/Code/04/47/mingribooks.xls')
df1 = df[['订单付款时间','买家会员名','联系手机','买家实际支付金额']]
df1 = df1.sort_values(by = ['订单付款时间'])
df1 = df1.set_index('订单付款时间')# 将日期设置为索引
#获取某个区间数据
df2 = df1['2018-05-11':'2018-06-10']
df2
买家会员名联系手机买家实际支付金额
订单付款时间
2018-05-11 11:37:00mrhy611**********55.86
2018-05-11 13:03:00mrhy801**********268.00
2018-05-11 13:27:00mrhy401**********55.86
2018-05-12 02:23:00mrhy271**********48.86
2018-05-12 21:13:00mrhy761**********268.00
2018-06-09 21:17:00yhhy471***********43.86
2018-06-09 22:42:00yhhy61***********167.58
2018-06-10 08:22:00yhhy41***********166.43
2018-06-10 09:06:00yhhy141***********137.58
2018-06-10 21:11:00yhhy241***********139.44

按不同时期统计并显示数据

按时期统计数据

主要通过DataFrame对象的resample()方法结合数据计算函数实现。resample方法主要应用于时间序列频率转换和重采样。它可以从日期中获取年、月、日、星期、季节等,再结合数据计算函数就可以实现按照不同时期统计数据。

df1 = =df1.resample('AS').sum()#年
df1 = =df1.resample('Q').sum()#季度
df1 = =df1.resample('M').sum()#月
df1 = =df1.resample('W').sum()#星期
df1 = =df1.resample('D').sum()#天

resample函数要求索引项必须为日期型,可以使用如下代码转换

df1.index = pd.to_datetime(df1.index)

按时期显示数据

使用to_period()方法将时间转换为时期,从而实现按时期显示数据,日期必须设置为索引列。

to_period(freq=None, axis: 'Axis' = 0, copy: 'bool' = True)

参数:

  • freq:字符串,周期索引的频率,默认为None
  • axis:行列索引,axis = 0表示行索引,1表示列索引
  • copy:是否复制数据,默认为True
  • 返回值:带周期索引的时间序列
df1.to_period('A')#按年
df1.to_period('Q')#按季度
df1.to_period('M')#按月
df1.to_period('W')#按星期
按时期统计并显示数据
df2.resample('AS').sum().to_period('A')#按年统计数据
df2.resample('Q').sum().to_period('Q')#按季度统计数据
df2.resample('M').sum().to_period('M')#按月统计数据
df2.resample('W').sum().to_period('W')#按星期统计数据

时间序列

重采样(resample方法)

在pandas中对时间序列的频率的调整成为重新采样,即将时间序列从一个频率转换到另一个频率的处理过程。resample方法对常规时间序列重新采样和频率转换,包括降采样和升采样两种。

resample(rule, axis=0, closed: 'Optional[str]' = None, label: 'Optional[str]' = None, convention: 'str' = 'start', kind: 'Optional[str]' = None, loffset=None, base: 'Optional[int]' = None, on=None, level=None, origin: 'Union[str, TimestampConvertibleTypes]' = 'start_day', offset: 'Optional[TimedeltaConvertibleTypes]' = None)

参数说明:

  • rule:字符串,偏移量表示目标字符串或对象转换。
  • how:用于产生聚合值的函数名或数组函数
  • axis:axis= 0 表示列,axis= 1表示行
  • fill_method:升采样时所使用的填充方法,ffill(用前值填充)或bfill方法(用后值填充)
  • closed:降采样时,时间区间的开闭,其值为left或right,left(左闭右开),right(左开右闭),默认为right
  • label:降采样时,如何设置聚合之的标签
  • convention:当重采样时,将低频率转换为高频率时所采用的约定,其值为start或end,默认为start
  • kind:聚合到时期(period)或时间戳(timestamp),默认聚合到时间序列的索引类型
  • loffset:聚合标签的时间校正值,默认为None
  • limit:向前或向后填充时,允许填充的最大时期数,默认为None
  • base:整型,默认为0.对于均匀细分1天的频率,聚合间隔的‘原点’
  • on:字符串,可选参数,默认为None。对DataFrame对象使用列代替索引进行重新采样。列必须与日期时间类似
  • level:字符串或整型,可选参数,默认为None。用于多索引,重新采样的级别名称或级别编号,级别必须与日期时间类似。
  • 返回值:重新采样对象

一分钟的时间序列转换为3分钟的时间序列

import pandas as pd
index = pd.date_range('02/02/2020',periods=9,freq= 'T')
series = pd.Series(range(9),index = index)
print(series)
print(series.resample('3T').sum())
2020-02-02 00:00:00    0
2020-02-02 00:01:00    1
2020-02-02 00:02:00    2
2020-02-02 00:03:00    3
2020-02-02 00:04:00    4
2020-02-02 00:05:00    5
2020-02-02 00:06:00    6
2020-02-02 00:07:00    7
2020-02-02 00:08:00    8
Freq: T, dtype: int64
2020-02-02 00:00:00     3
2020-02-02 00:03:00    12
2020-02-02 00:06:00    21
Freq: 3T, dtype: int64

降采样处理

降采样是按照周期由高频率转向低频率。如将5min采样时间变为一天

降采样会涉及数据的聚合

import pandas as pd
df = pd.read_excel('MR/Code/04/50/time.xls')
df1 = df.set_index('订单付款时间')
print(df1.resample('W').sum().head())
            买家实际支付金额  宝贝总数量
订单付款时间                     
2018-01-07   5735.91     77
2018-01-14   4697.62     70
2018-01-21   5568.77     74
2018-01-28   5408.68     53
2018-02-04   1958.19     19

升采样处理

升采样时周期由低频率转向高频率,将数据从低频率转换到高频率时,就不需要聚合了,将其重采样到日频率,默认会引入缺失值

升采样涉及到数据的填充,根据填充的方法不同,填充的数据也不同。

  • 不填充:空值用NaN代替,使用asfreq()方法
  • 用前值填充。用前面的值填充空值,使用ffill或pad,可以使用字母f代替。
  • 用后值填充,使用bfill方法,可以使用字母b代替。
import pandas as pd
import numpy as np
rng = pd.date_range('20200202',periods=2)
s1 = pd.Series(np.arange(1,3),index = rng)
s1_6h_asfreq = s1.resample('6H').asfreq()
print(s1_6h_asfreq)
s1_6h_pad = s1.resample('6H').pad()
print(s1_6h_pad)
s1_6h_ffill = s1.resample('6H').ffill()
print(s1_6h_ffill)
s1_6h_bfill = s1.resample('6H').bfill()
print(s1_6h_bfill)
2020-02-02 00:00:00    1.0
2020-02-02 06:00:00    NaN
2020-02-02 12:00:00    NaN
2020-02-02 18:00:00    NaN
2020-02-03 00:00:00    2.0
Freq: 6H, dtype: float64
2020-02-02 00:00:00    1
2020-02-02 06:00:00    1
2020-02-02 12:00:00    1
2020-02-02 18:00:00    1
2020-02-03 00:00:00    2
Freq: 6H, dtype: int32
2020-02-02 00:00:00    1
2020-02-02 06:00:00    1
2020-02-02 12:00:00    1
2020-02-02 18:00:00    1
2020-02-03 00:00:00    2
Freq: 6H, dtype: int32
2020-02-02 00:00:00    1
2020-02-02 06:00:00    2
2020-02-02 12:00:00    2
2020-02-02 18:00:00    2
2020-02-03 00:00:00    2
Freq: 6H, dtype: int32

时间序列数据汇总(ohlc函数)

使用ohlc函数可以得到金融领域的开始值(open)、结束值(close)、最高值(high)和最低值(low)

import pandas as pd
import numpy as np

rng = pd.date_range('2/2/2020',periods=12,freq = 'T')
s1 = pd.Series(np.arange(12),index = rng)
print(s1.resample('5min').ohlc())
                     open  high  low  close
2020-02-02 00:00:00     0     4    0      4
2020-02-02 00:05:00     5     9    5      9
2020-02-02 00:10:00    10    11   10     11

移动窗口数据计算(rolling函数)

由于时点的数据波动较大,某一点的数据就不能很好的表现它本身的特性,于是就有了“移动窗口”的概念,简单的说,为了提升数据的可靠性,将某个点的取值扩大到包含这个点的一段区间,用区间进行判断,这个区间就是窗口。

rolling(window: 'Union[int, timedelta, BaseOffset, BaseIndexer]', min_periods: 'Optional[int]' = None, center: 'bool_t' = False, win_type: 'Optional[str]' = None, on: 'Optional[str]' = None, axis: 'Axis' = 0, closed: 'Optional[str]' = None)

参数:

  • window:时间窗口的大小,有两种形式,即int或offset。如果使用int,则数值表示计算统计量的观测值的数量,即向前几个数据;如果使用offset,则表示时间窗口的大小。
  • min_periods:每个窗口最少包含的观测值数量,小于这个值的窗口结果为NA。值可以是int,默认值为None。offset情况下,默认值为1
  • center:吧窗口的标签设置为居中,默认为false,居右
  • win_type:窗口的类型。截取窗的各种函数。
  • on:可选参数
  • axis:axis= 0列,默认列
  • closed:定义区间的开闭
  • 返回值:为特定操作而生成的窗口或移动窗口子类。
import pandas as pd
index = pd.date_range('20200201','20200215')
data = [3,6,7,4,2,1,3,8,9,10,12,15,13,22,14]
s1_data = pd.Series(data,index = index)
print(s1_data)

s1_data.rolling(3).mean()
2020-02-01     3
2020-02-02     6
2020-02-03     7
2020-02-04     4
2020-02-05     2
2020-02-06     1
2020-02-07     3
2020-02-08     8
2020-02-09     9
2020-02-10    10
2020-02-11    12
2020-02-12    15
2020-02-13    13
2020-02-14    22
2020-02-15    14
Freq: D, dtype: int64

2020-02-01          NaN
2020-02-02          NaN
2020-02-03     5.333333
2020-02-04     5.666667
2020-02-05     4.333333
2020-02-06     2.333333
2020-02-07     2.000000
2020-02-08     4.000000
2020-02-09     6.666667
2020-02-10     9.000000
2020-02-11    10.333333
2020-02-12    12.333333
2020-02-13    13.333333
2020-02-14    16.666667
2020-02-15    16.333333
Freq: D, dtype: float64
s1_data.rolling(3,min_periods=1).mean()
2020-02-01     3.000000
2020-02-02     4.500000
2020-02-03     5.333333
2020-02-04     5.666667
2020-02-05     4.333333
2020-02-06     2.333333
2020-02-07     2.000000
2020-02-08     4.000000
2020-02-09     6.666667
2020-02-10     9.000000
2020-02-11    10.333333
2020-02-12    12.333333
2020-02-13    13.333333
2020-02-14    16.666667
2020-02-15    16.333333
Freq: D, dtype: float64

综合应用

excel多表合并

import pandas as pd
import glob
filearray = []
filelocation = glob.glob(r'MR/Code/04/example/01/aa/*.xlsx')#指定目录下所有的excel文件
# 遍历指定目录
for filename in filelocation:
    filearray.append(filename)
    print(filename)
res = pd.read_excel(filearray[0])#读取第一个excel文件
#顺序读取excel文件并进行合并
for i in range(1,len(filearray)):
    A = pd.read_excel(filearray[i])
    res = pd.concat([res,A],ignore_index=True,sort = False)
print(res.index)

#写入excel文件,并保持
writer = pd.ExcelWriter('all.xlsx')
res.to_excel(writer,'sheet1')
writer.save()

股票行情数据分析

股票数据包括开盘价、收盘价、最高价、最低价、成交量等多个指标。收盘价是当日行情的标准,也是下一个交易日开盘价的依据,可以预测未来证券市场行情,因此一般采用收盘价作为计算依据。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
aa = r'MR/Code/04/example/02/000001.xlsx'
df = pd.DataFrame(pd.read_excel(aa))
df['date']= pd.to_datetime(df['date'])#将数据类型转换为日期类型
df = df.set_index('date')#将date设置为index
df = df[['close']]
df['20天'] = np.round(df['close'].rolling(window= 20,center = False).mean(),2)
df['50天'] = np.round(df['close'].rolling(window= 50,center = False).mean(),2)
df['200天'] = np.round(df['close'].rolling(window= 200,center = False).mean(),2)
plt.rcParams['font.sans-serif']=['SimHei']# 解决中文乱码
df.plot(secondary_y = ['收盘价','20','50','200'],grid = True)
plt.legend(('收盘价','20天','50天','200天'),loc = 'upper right')

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值