复习DataFrame结构
DataFrame是表格型的数据结构,同时有行标签和列标签。DataFrame结构的特点如下:
1.DataFrame每一列的标签值允许使用不同的数据类型
2.DataFrame是表格型的数据结构,具有行和列
3.DataFrame中的每个数据值都可以被修改
4.DataFrame结构的行数、列数允许增加和删除。
5.DataFrame有两个方向的标签轴,分别是行标签和列标签
6.DataFrame可以对行和列执行算术运算。
一、创建DataFrame对象
pandas.DataFrame(data=None, index=None, columns=None,dtype=None,copy=None)
data:输入的数据,可以是ndarray,series,list,dict,标量以及一个DataFrame
index:行标签,如果没有传递index值,则默认行标签是RangeIndex(0,1,2,3…n),n代表data元素个数
columns:列标签,如果没有传递columns值,则默认标签是RangeIndex(0,1,2…n)
dtype:要强制的数据类型,只允许使用一种数据类型,如果没有,自行推断。
copy:从输入复制数据。对于dict数据,copy=True,重新复制一份。对于dataFrame或ndarray输入,copy=False.
1.使用普通列表创建:data = [1,2,3,4]\n df = pd.DataFrame(data)
2.使用嵌套列表创建data = [["xiaowang",20],["Lily",30],["Anne",40]]\n df = pd.DataFrame(data)
3.使用列表嵌套字典创建
`data = [{'a':1, "b":2},{"a":5,"b":10,"c":20}]
df = pd.DataFrame(data, index=["first","second"])#指定行标签`
4.使用字典嵌套列表创建
`data = {"Name":['关羽','刘备','张飞','曹操'],'Age':[28,34,29,42]}
df = pd.DataFrame(data)`
5.使用Series创建
`d = {'one':pd.Series([1,2,3],index=['a','b','c']),
'two':pd.Series([1,2,3,4],index=['a','b','c','d'])}
df = pd.DataFrame(d)`
二、列操作DataFrame
DataFrame可以使用列标签来完成数据的选取、添加和删除操作。
选取列:
data = {"Name":['关羽','刘备','张飞','曹操'],'Age':[28,34,29,42]}
print(df['Name'])
添加列:
d = {'one':pd.Series([1,2,3],index=['a','b','c']),
'two':pd.Series([1,2,3,4],index=['a','b','c','d'])}
df = pd.DataFrame(d)
df['three'] = pd.Series([10,20,30],index=['a','b','c'])
还可以用insert()方法添加:df.insert(2,column='three',value=[1,2,3,4])
df.insert(loc, column, value, allow_duplicates=False)
2.删除数据列del df['one']
或df.pop('two')
,pop有返回值
三、行操作DataFrame
1.标签选取
需要借助loc属性来完成:
d = {'one':pd.Series([1,2,3],index=['a','b','c']),
'two':pd.Series([1,2,3,4],index=['a','b','c','d'])}
df = pd.DataFrame(d)
df.loc['b']
按标签访问一组行和列df.loc['b','one']
按布尔数组访问一组行和列df.loc[['a','b'],['one','two']]
2.数值型索引和切片
数值型索引,需要使用iloc属性
data = {"Name":['关羽','刘备','张飞','曹操'],'Age':[28,34,29,42]}
index = ["rank1", "rank2", "rank3", "rank4"]
df = pd.DataFrame(data, index=index)
df.iloc[1:3]#获得位置索引1行到3行,但是不包括3的数据
切片直接提取行:df[1:3]
4.添加数据行
append()函数
df.append(other, ignore_index=False, verify_integrity=False, sort=False)
other:DataFrame或Series/dict类对象,或这些对象的列表
ignore_index:默认为False,若为True将不适用Index标签
verity_integrity:默认为False,若为True,则在创建具有重复项的索引时引发ValueError
sort:排序
1.追加字典
data = {
'Name':['关羽','刘备','张飞','曹操'],
"Age":[28,34,29,42],
"Salary":[5000,8000,4500,10000]
}
df = pd.DataFrame(data)
d2 = {"Name":"诸葛亮","Age":30}
df3 = df.append(d2,ignore_index=True)
2.追加Series
d2 = {"Name":"诸葛亮","Age":30}
s = pd.Series(d2, name="a")
df3 = df.append(s)
3.追加列表
list是一维,以列的形式追加:
a_1 = [10,"20",30]
df4 = df.append(a_1)
print(df4)
df5 = df.append(a_1,ignore_index=True)
print(df5)
输出:
0 Age Name Salary
0 NaN 28.0 关羽 5000.0
1 NaN 34.0 刘备 8000.0
2 NaN 29.0 张飞 4500.0
3 NaN 42.0 曹操 10000.0
0 10 NaN NaN NaN
1 20 NaN NaN NaN
2 30 NaN NaN NaN
0 Age Name Salary
0 NaN 28.0 关羽 5000.0
1 NaN 34.0 刘备 8000.0
2 NaN 29.0 张飞 4500.0
3 NaN 42.0 曹操 10000.0
4 10 NaN NaN NaN
5 20 NaN NaN NaN
6 30 NaN NaN NaN
list是二维,以行的形式追加
a_2 = [[10,"20",30]]
df5 = df.append(a_2)
print(df5)
df6 = df.append(a_2,ignore_index=True)
print(df6)
输出:
0 1 2 Age Name Salary
0 NaN NaN NaN 28.0 关羽 5000.0
1 NaN NaN NaN 34.0 刘备 8000.0
2 NaN NaN NaN 29.0 张飞 4500.0
3 NaN NaN NaN 42.0 曹操 10000.0
0 10.0 20 30.0 NaN NaN NaN
0 1 2 Age Name Salary
0 NaN NaN NaN 28.0 关羽 5000.0
1 NaN NaN NaN 34.0 刘备 8000.0
2 NaN NaN NaN 29.0 张飞 4500.0
3 NaN NaN NaN 42.0 曹操 10000.0
4 10.0 20 30.0 NaN NaN NaN
list是三维,只添加一个值
s = [[[1,2,3]]]
df.append(s)
输出:
0 Age Name Salary
0 NaN 28.0 关羽 5000.0
1 NaN 34.0 刘备 8000.0
2 NaN 29.0 张飞 4500.0
3 NaN 42.0 曹操 10000.0
0 [1, 2, 3] NaN NaN NaN
5.删除数据行
df.drop(0)#删除第0行数据
四、DataFrame常用的属性和方法
学习新内容:
python time模块
a.timestamp时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
b.struct_time时间元组,共有九个元素组
c.format time格式化时间,已格式化的结构使时间更具有可读性。包括自定义格式和固定格式。
一、主要time生成方法和time格式转换方法示例
import time
生成timestamp:time.time()
输出:
1657874422.2077966
作用
可以进行程序的计时:
#程序开始时间
start_time = time.time()
#程序
s=""
for i in range(5):
s += str(i)
# time.sleep(1)
end_time = time.time()
print("程序消耗时间=",end_time-start_time)
输出:
程序消耗时间= 0.0069806575775146484
生成struct_time:
#timestamp to struct_time本地时间
my_time = time.localtime()
print(my_time)
输出:
time.struct_time(tm_year=2022, tm_mon=7, tm_mday=15, tm_hour=16, tm_min=43, tm_sec=51, tm_wday=4, tm_yday=196, tm_isdst=0)
打印年月日:
print(my_time.tm_year)
print(my_time.tm_mon)
print(my_time.tm_mday)
输出:
2022
6
13
格式化字符串到struct_time:
time.strptime('2011-05-05 16:37:06','%Y-%m-%d %X')
输出:
time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1)
显示当前格式化后的时间:
time.strftime('%Y-%m-%d %X')
'2022-07-15 16:52:33'
显示指定struct_time的时间:
time.strftime('%Y-%m-%d %X', time.localtime(1657874422))
输出:
'2022-07-15 16:40:22'
对’2011-5-25 16:37:06’ 加10天:
my_str = '2011-05-25 16:37:06'
st = time.strptime(my_str,'%Y-%m-%d %X')
after_10 = time.mktime(st)+24*60*60*10
time.strftime('%Y-%m-%d %X', time.localtime(after_10))
输出:
'2011-06-04 16:37:06'
format time结构化表示
格式 含义
%Y -年[0001,…,2018,2019,…,9999]
%m -月[01,02…,30,31]
%d -天[01,02,…,30,31]
%H -小时[00,01,…58,59]
%S -秒[00,01,…,58,59]
%X 本地相应时间
%y 去掉世纪的年份(00-99)
常见格式化:
my = 'aaa'
print('%s' % my)
my_int = 1
print('%d' % my_int)
print("我们在{}工作".format('家里'))
addr = "家里"
print(f"我们在{addr}工作")
输出:
aaa
1
我们在家里工作
我们在家里工作
做一个倒计时:
for i in range(5):
print('\r','%s秒!' %(5-i), end="")
time.sleep(1)
print('\r',"发射!!!!!")#'\r'将光标退回到开始位置
二 、datatime模块
datatime模块重新封装了time模块,提供的类有:data,time,datetime,timedelta,tzinfo
1.data类
datetime.data(year,month,day)
静态方法和字段
data.today():返回一个表示当前本地日期的data对象
data.fromtimestamp(timestamp):根据给定的时间戳,返回一个data对象
from datetime import date
打印当前时间:
import time
print('date.today():', date.today())
print('date.fromtimestamp():', date.fromtimestamp(time.time()))
输出:
date.today(): 2022-07-15
date.fromtimestamp(): 2022-07-15
打印时间戳类型
print(type(date.fromtimestamp(1650177508)))
print(date.fromtimestamp(1650177058))
输出:
<class 'datetime.date'>
2022-04-17
其他方法和属性
如 d1 = data(2011,06,03)#data对象
d1.year、d1.month、d1.day:年、月、日
d1.replace(year、month、day):生成一个新的日期对象,用参数指定的年、月、日代替原有对象中的属性。(原有对象仍保持不变)
d1.timetuple():返回日期对应的time.struct_time对象
d1.weekday():返回weekday,如果是星期一,返回0;如果是星期2,返回1,依次类推
d1.isoweekday():返回weekday,如果是星期一,返回1,如果是星期二,返回2,以此类推
d1.isoformat():返回格式如’YYYY-MM-DD‘的字符串
d1.strftime(fmt):和time模块format相同
.replace()使用
now = date.today()
print(now)
date.today().replace(day=1)
输出:
2022-07-15
datetime.date(2022, 7, 1)
.isoformat()使用
now.isoformat()
now.isoformat()
输出:
'2022-07-15'
.isoweekday()使用
now.isoweekday()
输出:
5
.strftime()使用:
#自定义输出格式
now.strftime('%Y.%m.%d')
输出:
'2022.07.15'
1串:
now = date(2021, 10, 26)
print(now.year,now.month,now.day)
tomorrow = now.replace(day=1)
print('now:',now,',当月第一天:',tomorrow)
print('timetuple():',now.timetuple())
print('weekday():',now.weekday())
print('isoweekday():',now.isoweekday())
print('isoformat():',now.isoformat())
print('strftime():',now.strftime("%Y.%m.%d"))
输出
2021 10 26
now: 2021-10-26 ,当月第一天: 2021-10-01
timetuple(): time.struct_time(tm_year=2021, tm_mon=10, tm_mday=26, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=299, tm_isdst=-1)
weekday(): 1
isoweekday(): 2
isoformat(): 2021-10-26
strftime(): 2021.10.26
2.dataetime类
datetime相当于date和time结合起来
datetime.datetime (year, month, day[ , hour[ , minute[ , second[ , microsecond[ , tzinfo] ] ] ] ] ])
静态方法
datetime.today():返回一个表示当前本地时间的datetime对象
datetime.now():返回一个表示本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间
datetime.fromtimestamp(timestamp[,tz]:根据时间戳创建一个datetime对象,参数tz指定时区信息
`datetime.strptime(date_string,format):`
可根据一个表示时间的字符串和对应的格式字符串创建来一个 datetime 对象。
datetime.strftime()的使用
from datetime import datetime
now = datetime.now()
print(type(now))
#将datetime转化为指定格式的字符串
print(now.strftime('%Y-%m-%d %X'))
print(now.strftime('%Y-%m-%d %H:%M'))
输出:
<class 'datetime.datetime'>
2022-07-15 17:52:34
2022-07-15 17:52
datetime.today()的使用
datetime.today()
输出:
datetime.datetime(2022, 7, 15, 17, 53, 20, 430469)
使用strptime 将字符串转化为datetime:
my_str = '2021-11-10 10:23'
print(datetime.strptime(my_str,'%Y-%m-%d %H:%M'),type(datetime.strptime(my_str,'%Y-%m-%d %H:%M')))
#需要注意,将字符串转化为datetime数据类型,格式需要统一
my_str = '10/11/2021 10:23'
print(datetime.strptime(my_str,'%d/%m/%Y %H:%M'))
输出:
2021-11-10 10:23:00 <class 'datetime.datetime'>
2021-11-10 10:23:00
3.timedelta类,时间加减
使用timedelta可以在日期上做天,小时,分钟,秒,毫秒,微秒的计算,计算月份需要另外的办法
from datetime import datetime
from datetime import timedelta
dt = datetime.now()
#日期减一天
dt_1 = dt + timedelta(days=-1)#昨天
dt_11 = dt - timedelta(days=1)#昨天
dt3 = dt + timedelta(days=1 )#明天
print("dt:", dt_1)
print("dt_11:", dt_11)
print("dt3:", dt3)
输出:
dt: 2022-07-17 16:16:18.892462
dt_11: 2022-07-17 16:16:18.892462
dt3: 2022-07-19 16:16:18.892462
明天的datatime -昨天的datetime:
s = dt3 - dt_1
print(s.days)
print(s.total_seconds())
输出:
2
172800.0
pandas时间处理基础
pandas提供了四种类型的生成日期时间的对象:日期时间、时间增量、时间跨度、日期偏移量,如2020年12月6日13点37分50秒
(1)日期时间(Data times):具有时区支持的特定日期和时间。与python标准库中的datetime.datetime类似。
(2)时间增量(Time Deltas):绝对持续时间,用于在指定时间点的基础上增加指定的增量,如在某年月日的基础上增加2天,增加2个月,减少4小时等,最后产生一个新的时间点
(3)时间跨度(Time Span):由时间点及其相关周期定义的时间跨度,如连续产生一年四个季度的时间序列。
(4)时间偏移(Date Offsets):以日历计算的相对持续时间,表示时间间隔,两个时间点之间的长度,如周、日、月、季度、年
一般情况下,时间序列主要是Series或DataFrame的时间型索引,可以用时间元素进行操控。
一、时间序列类型
1. TimeStamp时间戳
python datetime的替代
大多数情况能与python的Datetime呼唤
该类型用于组成DatetimeIndex的条目,以及pandas中面向其它时间序列的数据结构。
将字符串或unix时间转换为pandas对应的时间戳
pandas.Timestamp(ts_input=<object object>,freq=None,tz=None,unit=None,
year=None,month=None,day=None,hour=None,minute=None,second=None,
microsecond=None,nanosecond=None,tzinfo=Zone,*,fold=None)
ts_input:要转换时间戳的值
freq:时间戳具有的偏移量
unit:用于转换的单位
例子:转换类似日期时间的字符串
pd.Timestamp('2022-01-01')
输出:Timestamp('2022-01-01 00:00:00')
pd.Timestamp('2021-12-15 12')
输出:pd.Timestamp('2021-12-15 12')
pd.Timestamp('01-01-2022 12')
输出:Timestamp('2022-01-01 12:00:00')
pd.Timestamp('2022-01')
输出:Timestamp('2022-01-01 00:00:00')
pd.Timestamp('2022')
输出:Timestamp('2022-01-01 00:00:00')
unit参数为s:
这里将转换以秒为单位表示的Unit历元的浮点值
1970年1月1日是Unit系统的起始时间
举例:
pd.Timestamp(time.time(),unit="s")
输出:
Timestamp('2022-07-18 08:36:41.554873228')
可以转换为整数值:
pd.Timestamp(int(time.time()),unit="s")
输出:
Timestamp('2022-06-13 09:31:50')
不加unit参数:
pd.Timestamp(time.time())
输出:
Timestamp('1970-01-01 00:00:01.655112748')
year,month,day,hour,minute,second,microsecond单独设置时间
举例:
pd.Timestamp(2022,1,1,12)
输出:Timestamp('2022-01-01 12:00:00')
提供年月日:
pd.Timestamp(year=2022,month=1,day=1)
输出:
Timestamp('2022-01-01 00:00:00')
最小要设置到day:
pd.Timestamp(year=2022,month=1)
报错:
2.时间间隔Timedelta——实现datetime加减
持续时间,即两个日期或时间之间的差异
与python的datetime.timedelta,在大多数情况下可互换
pd.Timedelta(
value=<object object at 0x000001BE55DCFE80>,
unit=None,
**kwargs,
)
value:数值或者Timedelta
unit:如果输入是整数,则表示输入的单位‘M’,‘W’,‘D’,‘T’,‘S’
举例:
时间加减:
ts = pd.Timestamp('2022-01-01 12')
ts + pd.Timedelta(-1, "D")
输出:
Timestamp('2021-12-31 12:00:00')
td = pd.Timedelta(days = 5,minutes=50, seconds=20)
ts + td
输出:
Timestamp('2022-01-06 12:50:20')
计算秒数:
td.total_seconds()
输出:435020.0
计算5天后的时间
print(time.time()+td.total_seconds())
pd.Timestamp(int(time.time()+td.total_seconds()),unit='s')
输出:
Timestamp('2022-07-23 09:41:33')
计算当前时间往后100天的日期(使用python时间戳):
now = datetime.datetime.now()
print(now)
#计算当前时间往后100天的日期
dt = now + pd.Timedelta(days=100)
print(dt,type(dt))
dt.strftime('%Y-%m-%d')
输出:
2022-07-18 16:52:18.113087
2022-10-26 16:52:18.113087 <class 'datetime.datetime'>
'2022-10-26'
使用pandas时间戳:
dt = pd.Timestamp(int(time.time()),unit='s')
dt + datetime.timedelta(days=100)
输出:
Timestamp('2022-10-26 08:56:03')
3.时间转化to_datetime
to_datetime 转换时间戳
能快速将字符串转化为时间戳。
传递Series时,返回一个Series(具有相同的索引),类似列表的则转化为DatetimeIndex
to_datetime(arg,errors='raise',dayfirst=False,yearfirst=False,utc=None,format=None,unit=None,infer_datetime_format=False,origin='unix')
arg:要转换为日期时间的对象
errors:错误处理
If 'raise',将引发异常
If 'coerce':无效的转换,使用NaT
If 'ignore':无效的转换,使用输入的数据
dayfirst:转换时指定日期分析顺序 yearfirst
utc:控制与时区相关的解析、本地化和转换(忽略)
format:用于分析时间的strftime,例如"%d/%m/%Y",自定义格式
unit:D,s,ms将时间戳转换为datetime
origin:定义参考日期。数值将被解析为自该参考日期起的单位数。
处理各种输入格式
1)从一个数据帧的多个列中组装日期时间
如[‘year’,‘month’,‘day’,‘minute’,‘second’]
也可以是相同的复数形式
举例:
df = pd.DataFrame({'year':[2015,2016],'month':[2,3],'day':[4,5]})
print(df)
pd.to_datetime(df)
输出:
2)将字符串转datetime
举例:
pd.to_datetime(["2005/11/23","2010.12.31"])
输出:
DatetimeIndex(['2005-11-23', '2010-12-31'], dtype='datetime64[ns]', freq=None)
3).将unix时间转为时间戳
pd.to_datetime([1349720105,1349806505],unit="s")
输出:
DatetimeIndex(['2012-10-08 18:15:05', '2012-10-09 18:15:05'], dtype='datetime64[ns]', freq=None)
4)自动识别异常
pd.to_datetime('210605')
输出:
Timestamp('2005-06-21 00:00:00')
设置yearfirst:
pd.to_datetime('210605',yearfirst=True)
输出:
Timestamp('2021-06-05 00:00:00')
5).配合unit参数,使用非unix时间
origin参考起始时间:
pd.to_datetime([1,2,3],unit='D',origin=pd.Timestamp('2020-1-11'))
输出:
DatetimeIndex(['2020-01-12', '2020-01-13', '2020-01-14'], dtype='datetime64[ns]', freq=None)
不设置origin:
pd.to_datetime([1,2,3],unit="d")
输出:
pd.to_datetime([1,2,3],unit="d")
unit=“h”:
pd.to_datetime([1,2,3], unit='h', origin=pd.Timestamp('2020-01'))
输出:
DatetimeIndex(['2020-01-01 01:00:00', '2020-01-01 02:00:00',
'2020-01-01 03:00:00'],
dtype='datetime64[ns]', freq=None)
6)不可转化日期/时间
如果日期不符合时间戳限制,则传递errors='ignore’将返回原始输入,而不是引发任何异常
如果将非日期(不可解析)强制传递给NaT,传递errors='coerce’还会将越界日期强制传递给NaT
举例:
pd.to_datetime(['120211204','20210101'])#不是8位的
报错:
无效的转换,将使用输入的数据:
pd.to_datetime(['120211204','2021.02.01'],errors="ignore")
输出:
Index(['120211204', '2021.02.01'], dtype='object')
无效的转换,将使用NaT :
pd.to_datetime(['120211204','2021.02.01'],errors="coerce")
输出:
DatetimeIndex(['NaT', '2021-02-01'], dtype='datetime64[ns]', freq=None)
自动识别:
pd.to_datetime(pd.Series(["Jul 30, 2018","2018.05.10",None]))
输出:
0 2018-07-30
1 2018-05-10
2 NaT
dtype: datetime64[ns]
4.生成时间戳范围date_range和bdate_range
date_range和bdate_range
date_range()返回固定频率的DatetimeIndex
date_range(strat=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs )
start:生成日期的左边界
end:生成日期的右边界
periods:要生成的周期数
freq:频率,default'D',频率字符串可以有倍数,如‘5H’
tz:用于返回本地化日期时间索引的时区名称,例如‘Asia/Hong_Kong'。默认,生成的DatetimeIndex是时区初始索引。
normalize:默认False,在生成日期范围之前,将开始/结束日期标准化
name:默认None设置返回Datetimeindex name
1).指定值
默认包含开始时间和结束时间,默认频率使用D(天)
pd.date_range(start='1/1/2021', end='1/08/2021')
输出:
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
'2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08'],
dtype='datetime64[ns]', freq='D')
pd.date_range(start='2010',end='2011')
输出:
DatetimeIndex(['2010-01-01', '2010-01-02', '2010-01-03', '2010-01-04',
'2010-01-05', '2010-01-06', '2010-01-07', '2010-01-08',
'2010-01-09', '2010-01-10',
...
'2010-12-23', '2010-12-24', '2010-12-25', '2010-12-26',
'2010-12-27', '2010-12-28', '2010-12-29', '2010-12-30',
'2010-12-31', '2011-01-01'],
dtype='datetime64[ns]', length=366, freq='D')
2).指定开始日期,设置期间数
pd.date_range(start='1/1/2018',periods=8)
输出:
pd.date_range(start='1/1/2018',periods=8)
pd.date_range(start='1/1/2018',periods=8)
DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
'2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08'],
dtype='datetime64[ns]', freq='D')
3)指定开始、结束和期间;频率自动生成(线性间隔)
pd.date_range(start='2018-04-24',end='2018-04-27',periods=3)
输出:
DatetimeIndex(['2018-04-24 00:00:00', '2018-04-25 12:00:00',
'2018-04-27 00:00:00'],
dtype='datetime64[ns]', freq=None)
pd.date_range(start='2018-04-24',end="2018-04-27",periods=4)
输出:
DatetimeIndex(['2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27'], dtype='datetime64[ns]', freq=None)
4)不指定结束时间:
pd.date_range(start='2018-04-24',periods=4)
输出:
DatetimeIndex(['2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27'], dtype='datetime64[ns]', freq='D')
介绍频率
W-MON:从指定每周星期几开始算起
pd.date_range('2022/1/1','2022/2/1',freq = 'W-MON')
输出:
DatetimeIndex(['2022-01-03', '2022-01-10', '2022-01-17', '2022-01-24',
'2022-01-31'],
dtype='datetime64[ns]', freq='W-MON')
WOM-2WOM:每月的第几个星期几开始算
pd.date_range('2022/1/1','2022/5/1',freq = "WOM-2MON")
#这里是每月的第二个星期一
输出:
DatetimeIndex(['2022-01-10', '2022-02-14', '2022-03-14', '2022-04-11'], dtype='datetime64[ns]', freq='WOM-2MON')
默认freq=‘D’:每日历日:
pd.date_range('2022/1/1','2022/1/4')
输出:
DatetimeIndex(['2022-01-01', '2022-01-02', '2022-01-03', '2022-01-04'], dtype='datetime64[ns]', freq='D')
B:每工作日
pd.date_range('2022/1/1',"2022/1/5",freq="B")
输出:
DatetimeIndex(['2022-01-03', '2022-01-04', '2022-01-05'], dtype='datetime64[ns]', freq='B')
M:每月最后一个日历日,M- 是每月最后一天
pd.date_range('2017','2018',freq='M')
输出:
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-30',
'2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31',
'2017-09-30', '2017-10-31', '2017-11-30', '2017-12-31'],
dtype='datetime64[ns]', freq='M')
Q-月:指定月为季度末,每个季度的最后一月的最后一个日历日
print(pd.date_range('2017','2020',freq='Q-DEC'))
输出:
DatetimeIndex(['2017-03-31', '2017-06-30', '2017-09-30', '2017-12-31',
'2018-03-31', '2018-06-30', '2018-09-30', '2018-12-31',
'2019-03-31', '2019-06-30', '2019-09-30', '2019-12-31'],
dtype='datetime64[ns]', freq='Q-DEC')
A-月:每年指定月份的最后一个日历日
print(pd.date_range('2017','2020',freq = 'A-DEC'))
输出:
DatetimeIndex(['2017-12-31', '2018-12-31', '2019-12-31'], dtype='datetime64[ns]', freq='A-DEC')
B,(M,Q,A),S 分别代表了工作日,(以月为频率,以日为频率,以年为频率)
M:每月最后一个工作日
BQ-月:指定月为季度末,每个季度末最后一月的最后一个工作日
BA-月:每年指定月份的最后一个工作日
pd.date_range('2017','2018',freq="BM")
输出:
DatetimeIndex(['2017-01-31', '2017-02-28', '2017-03-31', '2017-04-28',
'2017-05-31', '2017-06-30', '2017-07-31', '2017-08-31',
'2017-09-29', '2017-10-31', '2017-11-30', '2017-12-29'],
dtype='datetime64[ns]', freq='BM')
pd.date_range()-日期范围:复合频率
print(pd.date_range('2017/1/1','2017/2/1',freq='7D'))#7天
print(pd.date_range('2017/1/1','2017/1/2',freq='2h30min'))
print(pd.date_range('2017','2018',freq='2M'))#2月,每月最后一个日历日
输出:
DatetimeIndex(['2017-01-01', '2017-01-08', '2017-01-15', '2017-01-22',
'2017-01-29'],
dtype='datetime64[ns]', freq='7D')
DatetimeIndex(['2017-01-01 00:00:00', '2017-01-01 02:30:00',
'2017-01-01 05:00:00', '2017-01-01 07:30:00',
'2017-01-01 10:00:00', '2017-01-01 12:30:00',
'2017-01-01 15:00:00', '2017-01-01 17:30:00',
'2017-01-01 20:00:00', '2017-01-01 22:30:00'],
dtype='datetime64[ns]', freq='150T')
DatetimeIndex(['2017-01-31', '2017-03-31', '2017-05-31', '2017-07-31',
'2017-09-30', '2017-11-30'],
dtype='datetime64[ns]', freq='2M')
normalize:在生成日期范围之前,将开始/结束日期表标准化
未加normalize:
pd.date_range(start = '1/1/2021 15:30',periods=10, name="mypd")
输出:
DatetimeIndex(['2021-01-01 15:30:00', '2021-01-02 15:30:00',
'2021-01-03 15:30:00', '2021-01-04 15:30:00',
'2021-01-05 15:30:00', '2021-01-06 15:30:00',
'2021-01-07 15:30:00', '2021-01-08 15:30:00',
'2021-01-09 15:30:00', '2021-01-10 15:30:00'],
dtype='datetime64[ns]', name='mypd', freq='D')
normalize=True:
pd.date_range(start = '1/1/2021 15:30',periods=10, name="mypd",normalize=True)
输出:
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
'2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08',
'2021-01-09', '2021-01-10'],
dtype='datetime64[ns]', name='mypd', freq='D')
freq=“H”:
pd.date_range(start = '1/1/2021 15:30',periods=10, name="mypd",freq="H")
输出:
DatetimeIndex(['2021-01-01 15:30:00', '2021-01-01 16:30:00',
'2021-01-01 17:30:00', '2021-01-01 18:30:00',
'2021-01-01 19:30:00', '2021-01-01 20:30:00',
'2021-01-01 21:30:00', '2021-01-01 22:30:00',
'2021-01-01 23:30:00', '2021-01-02 00:30:00'],
dtype='datetime64[ns]', name='mypd', freq='H')
normalize=True,freq=“H”:
pd.date_range(start = '1/1/2021 15:30',periods=10, name="mypd",normalize=True,freq="H")
输出:
DatetimeIndex(['2021-01-01 00:00:00', '2021-01-01 01:00:00',
'2021-01-01 02:00:00', '2021-01-01 03:00:00',
'2021-01-01 04:00:00', '2021-01-01 05:00:00',
'2021-01-01 06:00:00', '2021-01-01 07:00:00',
'2021-01-01 08:00:00', '2021-01-01 09:00:00'],
dtype='datetime64[ns]', name='mypd', freq='H')
closed :包含left 还是right ,默认start和end都包含
pd.date_range(start='1/1/2021',end='1/08/2021')
输出:
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
'2021-01-05', '2021-01-06', '2021-01-07', '2021-01-08'],
dtype='datetime64[ns]', freq='D')
closed=‘left’:只包含start
pd.date_range(start='1/1/2021',end='1/08/2021',closed='left')
输出:
pd.date_range(start='1/1/2021',end='1/08/2021',closed='left')
pd.date_range(start='1/1/2021',end='1/08/2021',closed='left')
DatetimeIndex(['2021-01-01', '2021-01-02', '2021-01-03', '2021-01-04',
'2021-01-05', '2021-01-06', '2021-01-07'],
dtype='datetime64[ns]', freq='D')
bdate_range(start=None,end=None,periods=None,freq='B')
返回固定频率的DatetimeIndex,默认频率为工作日
pd.date_range(start='2022-04-01',end='2022-05-01')
输出:
DatetimeIndex(['2022-04-01', '2022-04-02', '2022-04-03', '2022-04-04',
'2022-04-05', '2022-04-06', '2022-04-07', '2022-04-08',
'2022-04-09', '2022-04-10', '2022-04-11', '2022-04-12',
'2022-04-13', '2022-04-14', '2022-04-15', '2022-04-16',
'2022-04-17', '2022-04-18', '2022-04-19', '2022-04-20',
'2022-04-21', '2022-04-22', '2022-04-23', '2022-04-24',
'2022-04-25', '2022-04-26', '2022-04-27', '2022-04-28',
'2022-04-29', '2022-04-30', '2022-05-01'],
dtype='datetime64[ns]', freq='D')
5.时期频率转换asfreq
asfreq(freq, method=None, how=None, normalize=False, fill_value=None)
将时间序列转换为指定的频率
如果此数据帧的索引是PeriodIndex,则新索引是使用PeriodIndex转换原始索引的结果
否则,新指数将相当于pd,date_range(strat,end,freq=freq),其中start和end分别是原始索引中的第一个和最后一个条目
与新索引中未出现在原始索引中的任何时间步对应的值为空(NaN),除非提供了填充此类未知值得方法
ts = pd.Series(np.random.rand(4),index = pd.date_range('20170101','20170104')
)
print(ts)
输出:
2017-01-01 0.571041
2017-01-02 0.672145
2017-01-03 0.391133
2017-01-04 0.861033
Freq: D, dtype: float64
ts.asfreq('4H')
输出:
2017-01-01 00:00:00 0.333880
2017-01-01 04:00:00 NaN
2017-01-01 08:00:00 NaN
2017-01-01 12:00:00 NaN
2017-01-01 16:00:00 NaN
2017-01-01 20:00:00 NaN
2017-01-02 00:00:00 0.848298
2017-01-02 04:00:00 NaN
2017-01-02 08:00:00 NaN
2017-01-02 12:00:00 NaN
2017-01-02 16:00:00 NaN
2017-01-02 20:00:00 NaN
2017-01-03 00:00:00 0.987466
2017-01-03 04:00:00 NaN
2017-01-03 08:00:00 NaN
2017-01-03 12:00:00 NaN
2017-01-03 16:00:00 NaN
2017-01-03 20:00:00 NaN
2017-01-04 00:00:00 0.332361
Freq: 4H, dtype: float64
6.shift()-时间频率进行移位
shift(periods=1, freq=None, axis=0, fill_value=None)
按所需的时段数和可选的时间频率进行移位索引。
periods:要转换的时段数,可以是正面的,也可以是负面的
freq:若指定了freq,则索引值会移位,但数据不会重新对齐。也就是说,如果要在移动时扩展索引并保留原数据。
axis:{0 or 'index',1 or 'columns',None}转换方向
fill_value:填充值
按日期索引的dataframe:
df = pd.DataFrame(np.random.rand(16).reshape((4,4)),
index = pd.date_range('20210101','20210104'),
columns=list('ABCD'))
df
输出:
正数:数值后移,模式为行
df.shift(periods=2)
输出:
正数,数值后移 设置为列:
df.shift(periods=1, axis="columns")
输出:
正数,数值后移 NaN填充为0:
df.shift(periods=3, fill_value=0)
输出:
当设置freq时,对时间索引移动:
df.shift(periods=3, freq="D")#时间加3
默认移动行:
df.shift(1)
输出:
计算变化百分比,
per = df/df.shift(1)-1#这里计算,该时间戳与上一个时间戳相比,变化百分比
print(per)
二、Pandas时期:Period()
使用
示例:
p = pd.Period('2017')
p
输出:
Period('2017', 'A-DEC')
设置频率
频率为月:
p = pd.Period('2017-1', freq='M')
print(p,type(p))
输出:
2017-01 <class 'pandas._libs.tslibs.period.Period'>
通过加减整数可以实现对Period的移动
print(p+1)
print(p-2)
输出:
2017-02
2016-11
如果两个Period对象拥有相同频率,则它们的差就是它们之间的单位数量
pd.Period('2018', freq='M') - p
输出:
<12 * MonthEnds>
Period_range函数可用于创建规则的时期范围
rng = pd.period_range('2021-1-1','2021-6-1',freq='M')
rng
输出:
PeriodIndex(['2021-01', '2021-02', '2021-03', '2021-04', '2021-05', '2021-06'], dtype='period[M]')
日期做索引给Series:
pd.Series(np.random.rand(6), index=rng)
输出:
2021-01 0.563470
2021-02 0.116583
2021-03 0.394012
2021-04 0.160551
2021-05 0.417964
2021-06 0.176198
Freq: M, dtype: float64
PeriodIndex 类的构造函数允许直接使用一组字符串表示一段时期**
values = ['200103','200104','200105']
#必须指定freq
index = pd.PeriodIndex(values, freq='M')
index
输出:
PeriodIndex(['2001-03', '2001-04', '2001-05'], dtype='period[M]')
时期的频率转化asfreq
A-月 ,每年指定月份的最后一个日历日
p = pd.Period('2021',freq='A-DEC')
print(p)
print(p.asfreq('M'))
print(p.asfreq('D'))
print(p.asfreq('H'))
输出:
2021
2021-12
2021-12-31
2021-12-31 23:00
how=“start”:
p.asfreq('M', how="start")
输出:
Period('2021-01', 'M')
how=“end”:
p.asfreq('M', how="end")
输出:
Period('2021-12', 'M')
对于PeriodIndex或TimeSeries的频率转换方式相同
PeriodIndex:
rng = pd.period_range('2006','2009', freq="A-DEC")
rng
输出:
PeriodIndex(['2006', '2007', '2008', '2009'], dtype='period[A-DEC]')
TimeSeries:
ts = pd.Series(np.random.rand(len(rng)),rng)
ts
输出:
2006 0.302520
2007 0.049657
2008 0.753162
2009 0.155549
Freq: A-DEC, dtype: float64
how=‘s’:
ts.asfreq('M', how='s')#s-start
输出:
2006-01 0.302520
2007-01 0.049657
2008-01 0.753162
2009-01 0.155549
Freq: M, dtype: float64
写成一条语句:
ts2 = pd.Series(np.random.rand(len(rng)), index = rng.asfreq('D' ,how='start'))
ts2
输出:
2006-01-01 0.507270
2007-01-01 0.150846
2008-01-01 0.677443
2009-01-01 0.131656
Freq: D, dtype: float64
时间戳与时期之间的转换:pd.to_period()、pd.to_timestamp()
示例:
rng = pd.date_range('2017/1/1', periods = 10, freq = 'M')
#print(rng)
ts1 = pd.Series(np.random.rand(len(rng)),index=rng)
ts1
输出:
2017-01-31 0.141462
2017-02-28 0.733882
2017-03-31 0.628477
2017-04-30 0.246656
2017-05-31 0.485784
2017-06-30 0.714262
2017-07-31 0.221505
2017-08-31 0.258264
2017-09-30 0.073794
2017-10-31 0.121590
Freq: M, dtype: float64
to_period()参数为空时:ts1.to_period().head()
输出:
2017-01 0.141462
2017-02 0.733882
2017-03 0.628477
2017-04 0.246656
2017-05 0.485784
Freq: M, dtype: float64
参数为月:ts1.to_period('M')
输出:
2017-01 0.141462
2017-02 0.733882
2017-03 0.628477
2017-04 0.246656
2017-05 0.485784
2017-06 0.714262
2017-07 0.221505
2017-08 0.258264
2017-09 0.073794
2017-10 0.121590
Freq: M, dtype: float64
时间序列-重采样resample
Pandas中的resample,重新采样时间序列数据。
对象必须具有类似datetime的索引(DatetimeIndex、PeriodIndex或TimedeltaIndex),或将类似datetime的值传递给on或level关键字
DataFrame.resample(rule,closed=True,label=None,level=None)
rule:表示目标转换时的偏移量字符串或对象
closed:在降采样时,各时间段的哪一段是封闭的,'right'或'left',默认'right'
label:在降采样时,如何设置聚合值的标签,例如,9:30-9:35会被标记成9:0还是9:35,默认9:3
5
示例:
rng = pd.date_range('20170101',periods=12)
ts = pd.Series(np.arange(12),index=rng)
print(ts)
输出:
2017-01-01 0
2017-01-02 1
2017-01-03 2
2017-01-04 3
2017-01-05 4
2017-01-06 5
2017-01-07 6
2017-01-08 7
2017-01-09 8
2017-01-10 9
2017-01-11 10
2017-01-12 11
Freq: D, dtype: int32
将序列下采样到5天的数据箱中,并将放入数据箱中的时间戳相加:ts.resample('5D').sum()
输出得到一个新的聚合后的Series,聚合方式为求和::
2017-01-01 10
2017-01-06 35
2017-01-11 21
Freq: 5D, dtype: int32
实例:
print(ts.resample('5D').mean(),'->求平均值\n')
print(ts.resample('5D').max(),'->求最大值\n')
print(ts.resample('5D').min(),'->求最小值\n')
print(ts.resample('5D').median(),'->求中值\n')
print(ts.resample('5D').first(),'->返回第一个值\n')
print(ts.resample('5D').last(),'->返回最后一个值\n')
print(ts.resample('5D').ohlc(),'->OHLC重采样\n')
输出:
2017-01-01 2.0
2017-01-06 7.0
2017-01-11 10.5
Freq: 5D, dtype: float64 ->求平均值
2017-01-01 4
2017-01-06 9
2017-01-11 11
Freq: 5D, dtype: int32 ->求最大值
2017-01-01 0
2017-01-06 5
2017-01-11 10
Freq: 5D, dtype: int32 ->求最小值
2017-01-01 2.0
2017-01-06 7.0
2017-01-11 10.5
Freq: 5D, dtype: float64 ->求中值
2017-01-01 0
2017-01-06 5
2017-01-11 10
Freq: 5D, dtype: int32 ->返回第一个值
2017-01-01 4
2017-01-06 9
2017-01-11 11
Freq: 5D, dtype: int32 ->返回最后一个值
open high low close
2017-01-01 0 4 0 4
2017-01-06 5 9 5 9
2017-01-11 10 11 10 11 ->OHLC重采样
降采样
rng = pd.date_range('20170101',periods=12)
ts = pd.Series(np.arange(1,13), index = rng)
#print(ts)
ts.resample('5D').sum()
输出:
2017-01-01 15
2017-01-06 40
2017-01-11 23
Freq: 5D, dtype: int32
升采样及插值:
rng = pd.date_range('2017/1/1 0:0:0', periods = 5,freq = 'H')#按小时
ts = pd.DataFrame(np.arange(15).reshape(5,3),index = rng,
columns = ['a','b','c'])
print(ts)
print(ts.resample('15T').asfreq())#按分钟
print(ts.resample('15T').ffill())#按之前的数据填充
print(ts.resample('15T').bfill())#按之后的数据填充
#低频转高频,主要是如何让插值
#.asfreq():不做填充,返回Nan
#.ffill():向上填充
#.bfill():向下填充
输出:
a b c
2017-01-01 00:00:00 0 1 2
2017-01-01 01:00:00 3 4 5
2017-01-01 02:00:00 6 7 8
2017-01-01 03:00:00 9 10 11
2017-01-01 04:00:00 12 13 14
a b c
2017-01-01 00:00:00 0.0 1.0 2.0
2017-01-01 00:15:00 NaN NaN NaN
2017-01-01 00:30:00 NaN NaN NaN
2017-01-01 00:45:00 NaN NaN NaN
2017-01-01 01:00:00 3.0 4.0 5.0
2017-01-01 01:15:00 NaN NaN NaN
2017-01-01 01:30:00 NaN NaN NaN
2017-01-01 01:45:00 NaN NaN NaN
2017-01-01 02:00:00 6.0 7.0 8.0
2017-01-01 02:15:00 NaN NaN NaN
2017-01-01 02:30:00 NaN NaN NaN
2017-01-01 02:45:00 NaN NaN NaN
2017-01-01 03:00:00 9.0 10.0 11.0
2017-01-01 03:15:00 NaN NaN NaN
2017-01-01 03:30:00 NaN NaN NaN
2017-01-01 03:45:00 NaN NaN NaN
2017-01-01 04:00:00 12.0 13.0 14.0
a b c
2017-01-01 00:00:00 0 1 2
2017-01-01 00:15:00 0 1 2
2017-01-01 00:30:00 0 1 2
2017-01-01 00:45:00 0 1 2
2017-01-01 01:00:00 3 4 5
2017-01-01 01:15:00 3 4 5
2017-01-01 01:30:00 3 4 5
2017-01-01 01:45:00 3 4 5
2017-01-01 02:00:00 6 7 8
2017-01-01 02:15:00 6 7 8
2017-01-01 02:30:00 6 7 8
2017-01-01 02:45:00 6 7 8
2017-01-01 03:00:00 9 10 11
2017-01-01 03:15:00 9 10 11
2017-01-01 03:30:00 9 10 11
2017-01-01 03:45:00 9 10 11
2017-01-01 04:00:00 12 13 14
a b c
2017-01-01 00:00:00 0 1 2
2017-01-01 00:15:00 3 4 5
2017-01-01 00:30:00 3 4 5
2017-01-01 00:45:00 3 4 5
2017-01-01 01:00:00 3 4 5
2017-01-01 01:15:00 6 7 8
2017-01-01 01:30:00 6 7 8
2017-01-01 01:45:00 6 7 8
2017-01-01 02:00:00 6 7 8
2017-01-01 02:15:00 9 10 11
2017-01-01 02:30:00 9 10 11
2017-01-01 02:45:00 9 10 11
2017-01-01 03:00:00 9 10 11
2017-01-01 03:15:00 12 13 14
2017-01-01 03:30:00 12 13 14
2017-01-01 03:45:00 12 13 14
2017-01-01 04:00:00 12 13 14