将值分配给多索引数据帧的第一行

时间:2016-02-11 19:39:13

标签: python pandas dataframe

我有一个带有多级索引的数据框,看起来有点像这样:

                 value  diffs 
 ticker   date              
   A      22     0.55    NaN
          32    -2.50  -3.05
          76    -0.79  -0.56
   B      59    -1.01  -0.22
          72    -1.24  -0.23
   C      22    -1.29  -0.05
          63     1.65   2.94

如何更改每个级别的第一行,以便我可以获得:

                  value  diffs 
 ticker   date              
   A      22     0.55    0
          32    -2.50  -3.05
          76    -0.79  -0.56
   B      59    -1.01    0
          72    -1.24  -0.23
   C      22    -1.29    0
          63     1.65   2.94

3 个答案:

答案 0 :(得分:1)

您可以使用groupby,例如

df['diffs'] = df.values.groupby(level=0).apply(lambda x: (x-x.shift(1)).fillna(0))

答案 1 :(得分:0)

可能有一种更好的方法,但这有效,首先我们可以看到多索引由不同的级别和标签组成,标签在级别更改时向我们显示:

In [77]:
df.index

Out[77]:
MultiIndex(levels=[['A', 'B', 'C'], [22, 32, 59, 63, 72, 76]],
           labels=[[0, 0, 0, 1, 1, 2, 2], [0, 1, 5, 2, 4, 0, 3]],
           names=['ticker', 'date'])

因此我们可以从第一个标签数组构建一个系列,并使用shift检测关卡何时更改并使用它来索引df:

In [78]:    
labels = pd.Series(df.index.labels[0])
labels[labels != labels.shift()]

Out[78]:
0    0
3    1
5    2
dtype: int8

从上面的索引我们可以传递到iloc以选择每个顶级组的第一行:

In [82]:
df['diffs'].iloc[labels[labels != labels.shift()].index]

Out[82]:
ticker  date
A       22       NaN
B       59     -0.22
C       22     -0.05
Name: diffs, dtype: float64

我们现在可以分配值:

In [83]:
df['diffs'].iloc[labels[labels != labels.shift()].index] = 0
df
Out[83]:
             value  diffs
ticker date              
A      22     0.55   0.00
       32    -2.50  -3.05
       76    -0.79  -0.56
B      59    -1.01   0.00
       72    -1.24  -0.23
C      22    -1.29   0.00
       63     1.65   2.94

答案 2 :(得分:0)

解决问题的一种简单方法是转置数据框并应用循环。

T = df.T
for name in T.columns.levels[0]:
    T.loc[T.index[-1], name][0]=0

例如,根据您的数据,您将获得以下信息: (我没有添加姓名,我只是回复了NaN的{​​{1}})

-1