使用.rolling()

时间:2017-01-25 23:10:56

标签: python pandas

我一直在追踪一个奇怪的错误,或者至少是近期熊猫版本的行为改变(不确定何时发生了变化,有时在0.16.2之间 - 它工作正常 - 和0.19。 2)。

基本上,我想要平滑DataFrame中的几列,但我有MultiIndex的日期和ID,并且应在取消堆叠ID后应用平滑(即所有ID ,对于选定的列)。如果我在卸载后执行stack('id'),没问题,列的顺序保持不变。但是,如果在df_fat.rolling(...).mean()之后完成取消堆栈,则列将按字母顺序排序。此外,将平滑后的列分配回原始帧会将结果分配给错误的列,在我们的情况下会产生非常糟糕的结果。

现在,我知道对索引(和列)进行排序是明智的,但我很惊讶最后一个单元格([5]中的赋值)显然是错误的,甚至没有大熊猫的抱怨。这是熊猫的错误​​吗?至少会有警告吗?

总结一下,我看到两个问题:

  1. .rolling().func更改了列顺序:它按字母顺序对它们进行排序。
  2. slice = df不尊重列名称(如.join所示) - 只需插入值。
  3. 这是一个可重复的例子:

    In[1]:
    import numpy as np
    import pandas as pd
    import io
    
    str = """t,id,x,foo,bar
    2012-01-01,A,0,100,1
    2015-10-27,B,1,200,2
    2015-11-15,B,2,300,3
    """
    df = pd.read_csv(io.StringIO(str), parse_dates=[0], index_col=[0,1]).sort_index()
    df
    
    Out[1]:
                   x  foo  bar
    t          id             
    2012-01-01 A   0  100    1
    2015-10-27 B   1  200    2
    2015-11-15 B   2  300    3
    

    现在,我想要平滑两列foobar。首先,做一个'胖' df因此可以使用.rolling().mean()轻松完成平滑。 (还要注意null_index以保留NaN在原始位置的位置:

    In[2]:
    feat_names = ['foo', 'bar']
    df_fat = df[feat_names].unstack('id')
    null_index = df_fat.isnull()
    df_fat
    
    Out[2]:
                  foo         bar     
    id              A      B    A    B
    t                                 
    2012-01-01  100.0    NaN  1.0  NaN
    2015-10-27    NaN  200.0  NaN  2.0
    2015-11-15    NaN  300.0  NaN  3.0
    
    到目前为止,没问题。实际上,对于所选列,堆叠会产生原始df:

    In[3]:
    df_fat.stack('id')
    
    Out[3]:
                     foo  bar
    t          id            
    2012-01-01 A   100.0  1.0
    2015-10-27 B   200.0  2.0
    2015-11-15 B   300.0  3.0
    

    现在,让我们进行平滑处理:

    In[4]:
    df_fat = df_fat.rolling(center=False, window=2, min_periods=1).mean()
    df_fat.stack('id')
    
    Out[4]:
                   bar    foo
    t          id
    2012-01-01 A   1.0  100.0
    2015-10-27 A   1.0  100.0
               B   2.0  200.0
    2015-11-15 B   2.5  250.0
    

    请注意列的排序方式。然后,当试图分配回原始版本时,所有地狱都会松动,列值将被插入"不考虑列名:

    In[5]:
    df_fat[null_index] = np.NaN
    df[feat_names] = df_fat.stack('id')
    df
    
    Out[5]:
                   x  foo    bar
    t          id               
    2012-01-01 A   0  1.0  100.0
    2015-10-27 B   1  2.0  200.0
    2015-11-15 B   2  2.5  250.0
    

    请注意,明确重新排序分配右侧的列会产生预期结果:

    In[6]:
    df_fat[null_index] = np.NaN
    df[feat_names] = df_fat.stack('id')[feat_names]
    df
    
    Out[6]:
                   x    foo  bar
    t          id               
    2012-01-01 A   0  100.0  1.0
    2015-10-27 B   1  200.0  2.0
    2015-11-15 B   2  250.0  2.5
    

0 个答案:

没有答案