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