2015-10-15 119 views
3

我正在尝试使用熊猫数据框分析数星期内测量“X”的平均每日波动,但是时间戳/日期时间等被证明是特别地狱般的处理。花了好几个小时试图解决这个问题,我的代码变得越来越混乱,我认为我没有更接近解决方案,希望这里的某个人能够指引我朝着正确的方向前进。用熊猫分时数据框

我已测量的X在不同时间和在不同的日子,每天的结果保存到具有形式的数据帧:

Timestamp(datetime64)   X 

0 2015-10-05 00:01:38   1 
1 2015-10-05 06:03:39   4 
2 2015-10-05 13:42:39   3 
3 2015-10-05 22:15:39   2 

由于测量是在从每天我决定的变化作出的时间使用binning来组织数据,然后计算每个bin的平均值和STD,然后我可以绘制它们。我的想法是创建一个二进制位最终数据帧和X为测量的平均值,该“意见”一栏只是为了帮助理解:

 Time Bin  Observations  <X> 

0  00:00-05:59  [ 1 , ...]  2.3 
1  06:00-11:59  [ 4 , ...]  4.6 
2  12:00-17:59  [ 3 , ...]  8.5 
3  18:00-23:59  [ 2 , ...]  3.1 

但是我已经不兼容的时间之间遇到困难, datetime,datetime64,timedelta和binning使用pd.cut和pd.groupby,基本上我觉得我在黑暗中刺中,不知道“正确”的方式来解决这个问题。我能想到的唯一解决方案是通过数据框逐行迭代,但我真的很想避免必须这样做。

回答

4

每当我将时间序列数据按时间范围分组,这似乎是您在这里所做的,我只需创建一个“每小时”列并对其进行切片。另外,我通常将索引设置为日期时间值...虽然在这里没有必要。

# assuming your "timestamp" column is labeled ts: 
df['hod'] = [r.hour for r in df.ts] 

# now you can calculate stats for each bin 
ave = df[ (df.hod>=0) & (df.hod<6) ].mean() 

我认为存在使用df.resample这里的方法,但在时间序列的定义不清的开始/结束点,我认为这可能需要比上述方法更多的关注。

这是沿着你想要的?

0

不知道我有最好的答案,但我认为它可以正常工作。
首先,我会转换datetime64datetime使用这个职位,例如: Converting between datetime, Timestamp and datetime64

然后,如果我们假设你的第一列具有datetime,被称为TimeStamp,我会做这样的事情:

def bin_f(x): 
    if x.time() < datetime.time(6): 
     return "00:00-05:59" 
    elif x.time() < datetime.time(12): 
     return "06:00-11:59" 
    elif x.time() < datetime.time(18): 
     return "12:00-17:59" 
    else: 
     return "18:00-23:59" 

df["Bin"] = df["TimeStamp"].apply(bin_f) 
grouped = df.groupby("Bin") 
grouped['X'].agg(np.std) 

X是您列的名称。

0

我发现我的目的Mathiou的反应有帮助的,但修改了它如下:

def bin_f(x): 
    h = x.time() 
    if h < 6: 
     return "00:00-05:59" 
    elif h < 12: 
     return "06:00-11:59" 
    elif h < 18: 
     return "12:00-17:59" 
    else: 
     return "18:00-23:59"