使用pandas将非平衡面板聚合到时间序列

时间:2014-07-30 22:09:07

标签: python pandas

我有一个不平衡的面板,我正在尝试汇总到常规的每周时间序列。该小组如下所示:

Group     Date        value
 A       1/1/2000       5
 A       1/17/2000      10
 B       1/9/2000       3
 B       1/23/2000      7
 C       1/22/2000      20

为了更好地了解我正在寻找的东西,我要包括一个中间步骤,如果可能的话,我很乐意跳过。基本上需要填写一些数据,以便汇总。如您所见,观察之间的缺失周数是插值的。所有其他值都设置为零。

Group    Date        value
  A     1/1/2000      5
  A     1/8/2000      5
  A     1/15/2000     10
  A     1/22/2000     0
  B     1/1/2000      0
  B     1/8/2000      3
  B     1/15/2000     3
  B     1/22/2000     7
  C     1/1/2000      0
  C     1/8/2000      0
  C     1/15/2000     0
  C     1/22/2000     20

我正在寻找的最终结果如下:

 Date      value           
1/1/2000     5 = 5 + 0 + 0          
1/8/2000     8 = 5 + 3 + 0           
1/15/2000    13 = 10 + 3 + 0           
1/22/2000    27 = 0 + 7 + 20

我没有走得太远,设法创建一个小组:

panel = df.set_index(['Group','week']).to_panel()

不幸的是,如果我尝试重新采样,我会收到错误

panel.resample('W')
TypeError: Only valid with DatetimeIndex or PeriodIndex

3 个答案:

答案 0 :(得分:1)

假设df是您的第二个数周期数周,您可以尝试以下方法:

df.groupby('week').sum()['value']

groupby()及其应用程序的文档为here。它类似于SQL中的group-by函数。


要从第一个数据帧获取第二个数据帧,请尝试以下操作:

首先,准备一个将日期映射到一周的函数

def d2w_map(day):
    if day <=7:
        return 1
    elif day <= 14:
        return 2
    elif day <= 21:
        return 3
    else:
        return 4

在上面的方法中,第4周考虑从29到31天。但是你明白了。您可以根据需要进行修改。

其次,从第一个数据框中取出列表,并将天数转换为几周

df['Week'] = df['Day'].apply(d2w_map)
del df['Day']

第三,仅使用“Group”和“Week”列初始化第二个数据帧,并将“value”保留为out。现在假设您初始化的新数据帧为result,您现在可以进行连接

result = result.join(df, on=['Group', 'Week'])

最后,编写一个函数,用附近的元素填充'value'列中的NanNan是您需要插入的内容。由于我不确定你希望插值如何工作,我会留给你。


以下是如何更改d2w_map以将日期字符串转换为星期的整数

from datetime import datetime
def d2w_map(day_str):
    return datetime.strptime(day_str, '%m/%d/%Y').weekday()

返回值0表示星期一,1表示星期二,依此类推。

如果您安装了软件包dateutil,则该功能可以更强大:

from dateutil.parser import parse
def d2w_map(day_str):
    return parse(day_str).weekday()

有时候,你想要的东西已经被魔法实现了:)

答案 1 :(得分:0)

原来关键是重新采样groupby对象,如下所示:

df_temp = (df.set_index('date')
           .groupby('Group')
           .resample('W', how='sum', fill_method='ffill'))

ts = (df_temp.reset_index()
      .groupby('date')
      .sum()[value])

答案 2 :(得分:0)

使用此选项卡分隔test.txt:

    Group   Date    value
    A   1/1/2000    5
    A   1/17/2000   10
    B   1/9/2000    3
    B   1/23/2000   7
    C   1/22/2000   20

您可以跳过中间数据文件,如下所示。现在没时间。只要玩弄它就可以了。

    import pandas as pd
    import datetime
    time_format = '%m/%d/%Y'
    Y = pd.read_csv('test.txt', sep="\t")
    dates = Y['Date']
    dates_right_format = map(lambda s: datetime.datetime.strptime(s, time_format), dates)
    values = Y['value']
    X = pd.DataFrame(values)
    X.index = dates_right_format
    print X
    X = X.sort()
    print X
    print X.resample('W', how=sum, closed='right', label='right')

上次打印

                value
    2000-01-02      5
    2000-01-09      3
    2000-01-16    NaN
    2000-01-23     37