如何在groupby与apply操作后恢复索引和列标签?
Pandas groupby+apply后恢复原索引与列标签
问题场景
对带有多层列索引的DataFrame执行groupby(level="L1", axis=1),并通过apply调用scipy.stats.ttest_1samp计算每行p值时,返回结果是一个以L1为索引的Series,每个元素是对应组的p值numpy数组。需要将其转换为保留原行索引['a','b','c']、列标签为L1分类的标准DataFrame。
解决方法
方法1:在apply中直接返回带原索引的Series
在lambda函数里,将ttest返回的p值数组包装成指定原索引的Series,groupby+apply会自动拼接成目标DataFrame:
import pandas as pd import numpy as np from scipy import stats # 构造原始数据 df = pd.DataFrame(data=np.arange(0, 12).reshape(3, 4)) df.index = ["a", "b", "c"] df.columns = [["d", "d", "e", "e"], ["f", "g", "f", "g"]] df.columns.names = ["L1", "L2"] # 直接生成带原索引的DataFrame result_df = df.groupby(level="L1", axis=1).apply( lambda x: pd.Series(stats.ttest_1samp(x, axis=1, popmean=0).pvalue, index=df.index) )
执行后result_df的结构:
d e a 0.499999 0.125666 b 0.070447 0.048875 c 0.035714 0.023810
方法2:对返回的Series做后续转换
如果已经得到包含numpy数组的Series,可以通过tolist()提取数组,再构造DataFrame并调整索引:
# 先得到原始的Series结果 result_series = df.groupby(level="L1", axis=1).apply( lambda x: stats.ttest_1samp(x, axis=1, popmean=0).pvalue ) # 转换为目标DataFrame result_df = pd.DataFrame(result_series.tolist(), index=result_series.index).T result_df.index = df.index
两种方法都能得到保留原行索引、列标签为L1分类的DataFrame,满足数据处理需求。
内容的提问来源于stack exchange,提问作者goweon
相关产品推荐
相关产品推荐

