最初我有下表:
df=pd.DataFrame(
np.arange(4*8).reshape(4,8),
index=list('abcd'),
columns=pd.MultiIndex.from_arrays([list('EEEETTTT'), list('XXYYZZWW'), list('rsrsrsrs')] )
)
E T
X Y Z W
r s r s r s r s
a 0 1 2 3 4 5 6 7
b 8 9 10 11 12 13 14 15
c 16 17 18 19 20 21 22 23
d 24 25 26 27 28 29 30 31
我在'V'
多索引列旁边添加一个名为( , ,'s')
的新列,如下所示:
E T
X Y W Z
r s V r s V r s V r s V
a 0 1 0 2 3 0 6 7 0 4 5 0
b 8 9 0 10 11 0 14 15 0 12 13 0
c 16 17 0 18 19 0 22 23 0 20 21 0
d 24 25 0 26 27 0 30 31 0 28 29 0
我运行以下代码来获得以上结果:
dfl=[]
for name, x in df.groupby(level=[0, 1], axis=1):
index = pd.IndexSlice
x.loc[:,index[name[0],name[1],'V']]= 0
dfl.append(x)
pd.concat(dfl, axis=1)
现在,我尝试了以下“替代”方式来获得相同的结果:
def f(x):
idx = pd.IndexSlice
x.loc[:, idx[x.name[0], x.name[1], 'V']]=0
return x
df.groupby(level=[0,1], axis=1).apply(f)
但是,令我惊讶的是,结果表保持不变:
E T
X Y Z W
r s r s r s r s
a 0 1 2 3 4 5 6 7
b 8 9 10 11 12 13 14 15
c 16 17 18 19 20 21 22 23
d 24 25 26 27 28 29 30 31
pandas groupby.appy(func)应该允许func返回任何大小甚至标量的数据框。
这可能是个错误吗?
答案 0 :(得分:2)
partial bug与MutiIndex in columns
的分组有关。
如果使用MultiIndex in index
,则只需进行少量修改即可-删除用于分组的级别以避免重复级别。
通过对MultiIndex in index
进行转置来修改您的解决方案,应用函数并向后转置:
def f(x):
idx = pd.IndexSlice
x.loc[idx[x.name[0], x.name[1], 'V'], :]=0
x.index = x.index.droplevel([0,1])
return x
df = df.T.groupby(level=[0,1], axis=0).apply(f).T.astype(int)
print (df)
E T
X Y W Z
r s V r s V r s V r s V
a 0 1 0 2 3 0 6 7 0 4 5 0
b 8 9 0 10 11 0 14 15 0 12 13 0
c 16 17 0 18 19 0 22 23 0 20 21 0
d 24 25 0 26 27 0 30 31 0 28 29 0
def f(x):
idx = pd.IndexSlice
x.loc[idx[x.name[0], x.name[1], 'V'], :]=0
return x
df = df.T.groupby(level=[0,1], axis=0).apply(f).T.astype(int)
print (df)
E T
X Y W Z
E E T T
X Y W Z
r s V r s V r s V r s V
a 0 1 0 2 3 0 6 7 0 4 5 0
b 8 9 0 10 11 0 14 15 0 12 13 0
c 16 17 0 18 19 0 22 23 0 20 21 0
d 24 25 0 26 27 0 30 31 0 28 29 0