Python 为多索引数据帧的第一行赋值

Python 为多索引数据帧的第一行赋值,python,pandas,dataframe,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.2

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

                 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

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

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

解决此问题的一个简单方法是转置数据帧并应用循环

T = df.T
for name in T.columns.levels[0]:
    T.loc[T.index[-1], name][0]=0
例如,使用您的数据,您将获得以下信息: (我没有添加名称,只是通过
-1
回复
NaN


您可以使用
groupby
,例如

df['diff']=df.values.groupby(level=0)。应用(lambda x:(x-x.shift(1))。fillna(0))

data=np.array([[ 0.55, -1], [-2.50,  -3.05], [-0.79,  -0.56],
[-1.01,  -0.22], [-1.24,  -0.23], [-1.29,  -0.05], [ 1.65,   2.94]])

index=[np.array(['A', 'A', 'A', 'B', 'B', 'C', 'C']),
np.array(['22', '32', '76', '59', '72', '22', '63'])]

df=pd.DataFrame(data,index=index)
df
         0     1
A 22  0.55 -1.00
  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

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

df
         0     1
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