Pandas处理时间序列实战
数据处理中遇到以下数据格式的数据,对时间序列数据的处理更了解了一些,随手写下这篇小记:
数据格式
In [1] :import pandas as pd
import numpy as np
from pandas.tseries.offsets import *
In [2] :a = [11,"1天前","2019-08-05"]
b = [12,"5天前","2019-08-05"]
c = [13,"1个月前","2019-08-05"]
d = [14,"2019-08-05","2019-08-05"]
In [3] :df = pd.DataFrame([a,b,c,d])
df.columns = ["id","post_time","update_time"]
df
Out[3] :
id post_time update_time
0 11 1天前 2019-08-05
1 12 5天前 2019-08-05
2 13 1个月前 2019-08-05
3 14 2019-08-05 2019-08-05
因为要使用post_time进行聚合运算,且非标准时间格式的数据大概占了十分之一左右,所以不能舍弃,于是需要进行处理:
处理过程中了解了许多处理方法,虽然有的并不能解决问题,但更加了解对时间序列的处理:
1.通过条件定位数据并替换
定位数据:
使用df.loc[条件]来定位数据
替换数据:
In[10] :df.loc[df["post_time"]=="1天前","post_time"] =1
df.loc[df["post_time"]=="5天前","post_time"] =5
df.loc[df["post_time"]=="1个月前","post_time"] =30
2.格式化时间
查看DF信息:
现在的post_time,update_time是object类型,需要对其格式化:
3.时间偏移计算
for i in range(len(df)):
if df.post_time.iloc[i]==1:
a = df.update_time.iloc[i]-DateOffset(days=1)
df.post_time.iloc[i]=a
elif df.post_time.iloc[i]==5:
a = df.update_time.iloc[i]-DateOffset(days=5)
df.post_time.iloc[i]=a
elif df.post_time.iloc[i]==60:
a = df.update_time.iloc[i]-DateOffset(days=60)
df.post_time.iloc[i]=a
通过这种方法可以对这四行数据进行处理,但是实际处理中包含很多种,比如3秒前,5秒前,2周前。。。等等很多,所以不能一一列举,只能在想其他办法。
4.series.apply()和df.apply()
最终使用Python的datetime模块,构造方法,使用df.apply(function)的方法进行处理。
def new_time(df):
if '分钟' in df["post_time"] or '小时' in df["post_time"] or '秒' in df["post_time"]:
df["post_time"] = df["update_time"]
return df
elif '天' in df["post_time"]:
num = int(df["post_time"].split('天')[0])
df["post_time"] = df['update_time'] - datetime.timedelta(days=num)
return df
elif '周' in df["post_time"]:
num = int(df['post_time'].split('周')[0])
df["post_time"] = df['update_time'] - datetime.timedelta(days=num * 7)
return df
elif '月' in df["post_time"]:
num = int(df['post_time'].split('个月')[0])
df["post_time"] = df['update_time'] - datetime.timedelta(days=num * 30)
return df
else:
return df
df["update_time"] = pd.to_datetime(df["update_time"])
final = df.apply(new_time,axis=1)
搞定!!!