df有:
A B C
a 1 2 3
b 2 1 4
c 1 1 1
df要:
A B C
a 1 2 3
b 2 1 4
c 1 1 1
d 1 -1 1
我可以通过以下方式获得df的要求:
df.loc['d']=df.loc['b']-df.loc['a']
但是,我的实际df具有用于多个ID“ X”,“ Y”等的“ a”,“ b”,“ c”行。
A B C
X a 1 2 3
b 2 1 4
c 1 1 1
Y a 1 2 3
b 2 1 4
c 1 1 1
如何创建具有多个ID的相同输出? 我原来的方法:
df.loc['d']=df.loc['b']-df.loc['a']
失败KeyError:'b'
所需的输出:
A B C
X a 1 2 3
b 2 1 4
c 1 1 1
d 1 -1 1
Y a 1 2 3
b 2 2 4
c 1 1 1
d 1 0 1
答案 0 :(得分:1)
IIUC,
for i, sub in df.groupby(df.index.get_level_values(0)):
df.loc[(i, 'd'), :] = sub.loc[(i,'b')] - sub.loc[(i, 'a')]
print(df.sort_index())
或者也许
k = df.groupby(df.index.get_level_values(0), as_index=False).apply(lambda s: pd.DataFrame([s.loc[(s.name,'b')].values - s.loc[(s.name, 'a')].values],
columns=s.columns,
index=pd.MultiIndex(levels=[[s.name], ['d']], codes=[[0],[0]])
)).reset_index(drop=True, level=0)
pd.concat([k, df]).sort_index()
答案 1 :(得分:1)
如果要对多索引的特定级别进行操作,则数据重塑是一个有用的技巧。参见下面的代码,
result = (df.unstack(0).T
.assign(d=lambda x:x.b-x.a)
.stack()
.unstack(0))
答案 2 :(得分:0)
使用pd.IndexSlice
来切片a
和b
。调用diff
上的slice
和b
,然后rename
呼叫d
。最后,将其附加到原始df
idx = pd.IndexSlice
df1 = df.loc[idx[:,['a','b']],:].diff().loc[idx[:,'b'],:].rename({'b': 'd'})
df2 = df.append(df1).sort_index().astype(int)
Out[106]:
A B C
X a 1 2 3
b 2 1 4
c 1 1 1
d 1 -1 1
Y a 1 2 3
b 2 2 4
c 1 1 1
d 1 0 1