重新采样MultiIndex

时间:2018-08-10 13:16:29

标签: python pandas dataframe multi-index

我有一个DataFrame和一个MultiIndex。第一级是DatetimeIndex,每周一次。第二级是,第一级在各个分组之间是一致的。

我想按月对第一级进行分组,并进行前几周的行。

设置

midx = pd.MultiIndex.from_arrays([
    pd.date_range('2018-01-01', freq='W', periods=10).repeat(2),
    list('ABCDEFGHIJ' * 2)
], names=['Date', 'Thing'])

df = pd.DataFrame(dict(Col=np.arange(10, 30)), midx)

预期结果

df

                  Col    
Date       Thing     
2018-01-07 A       10    # This is the first week
           B       11    # of January 2018 
2018-01-14 C       12
           D       13
2018-01-21 E       14
           F       15
2018-01-28 G       16
           H       17
2018-02-04 I       18    # This is the first week
           J       19    # of February 2018
2018-02-11 A       20
           B       21
2018-02-18 C       22
           D       23
2018-02-25 E       24
           F       25
2018-03-04 G       26    # This is the first week
           H       27    # of March 2018
2018-03-11 I       28
           J       29

结果应为

                  Col    
Date       Thing     
2018-01-07 A       10    # This is the first week
           B       11    # of January 2018 
2018-02-04 I       18    # This is the first week
           J       19    # of February 2018
2018-03-04 G       26    # This is the first week
           H       27    # of March 2018

尝试

df.unstack().asfreq('M', 'ffill').stack()

                   Col
Date       Thing      
2018-01-31 G      16.0
           H      17.0
2018-02-28 E      24.0
           F      25.0

这在几个级别上都是错误的。

  1. 日期是实际的月底,而不是实际的观察日期。
  2. 事情不是正确的日期。请注意,我需要['A', 'B']的{​​{1}}而不是'2018-01-07'的东西。
  3. 我正在堆叠以使自己能够使用['G', 'H'],但这引入了asfreq并转换为nan
  4. 我不知道float发生了什么

2 个答案:

答案 0 :(得分:1)

你可以做

In [384]: date = df.index.get_level_values('Date')

In [385]: firstweek = date.to_frame().groupby(date.strftime('%Y-%m')).min()['Date']

In [386]: df[date.isin(firstweek)]
Out[386]:
                  Col
Date       Thing
2018-01-07 A       10
           B       11
2018-02-04 I       18
           J       19
2018-03-04 G       26
           H       27

详细信息

In [387]: date.to_frame().groupby(date.strftime('%Y-%m')).min()
Out[387]:
              Date
2018-01 2018-01-07
2018-02 2018-02-04
2018-03 2018-03-04

替代。

In [400]: fweek = df.assign(dt=date).resample('M', level='Date')['dt'].min()

In [401]: df[date.isin(fweek)]
Out[401]:
                  Col
Date       Thing
2018-01-07 A       10
           B       11
2018-02-04 I       18
           J       19
2018-03-04 G       26
           H       27

答案 1 :(得分:1)

如果每月的第一周只是该月的前7天,则可以像这样进行过滤

df[df.index.get_level_values(0).day <= 7]

                Col
Date       Thing     
2018-01-07 A       10
           B       11
2018-02-04 I       18
           J       19
2018-03-04 G       26
           H       27

除非您寻找的是在星期日结束的第一周,否则这种情况将不起作用。