如何在Pandas多索引DataFrame中用apply处理集合并访问索引
解决多索引DataFrame中apply修改指定列并访问索引的问题
首先咱们先理清问题根源:当你对整个DataFrame使用apply(axis=1)并返回一个标量(比如{x["A"]})时,Pandas会把这个标量广播到所有列,所以A和B列都会被赋值成相同的集合,这就是结果里两列重复的原因。
下面给你两种满足需求的解决方案,既保留多索引结构,又能在lambda里访问索引标签:
方法1:直接对目标列使用Series.apply(最简洁高效)
如果你只需要修改某一列(比如A列),直接对该列调用apply就好,而且在lambda里可以通过x.name访问对应的多索引元组(因为Series的每个元素的name就是它的索引值)。
示例代码:
# 基础需求:把A列的值转为集合 s['A'] = s['A'].apply(lambda x: {x}) # 如果需要访问索引标签(比如把first层级的标签加入集合) s['A'] = s['A'].apply(lambda x: {x, x.name[0], x.name[1]})
执行后基础需求版的结果:
A B first second bar one {1} 2 two {3} 4 foo one {5} 6 two {7} 8
这个方法不仅保留了多索引,还只修改目标列,性能也比对整个DataFrame apply更好。
方法2:对整个DataFrame apply并返回指定列的Series(适合多列处理场景)
如果你必须对整个DataFrame使用apply(axis=1)(比如需要同时处理多列),可以在lambda里返回一个和原列名匹配的Series,只修改目标列,其他列保留原值,同时通过row.name访问多索引标签。
示例代码:
s = s.apply(lambda row: pd.Series( { 'A': {row['A'], row.name[0]}, # row.name是多索引元组,row.name[0]取first标签,row.name[1]取second标签 'B': row['B'] # 保留B列原数值 } ), axis=1)
执行后结果:
A B first second bar one {1, 'bar'} 2 two {3, 'bar'} 4 foo one {5, 'foo'} 6 two {7, 'foo'} 8
为什么原方法会出现重复?
当apply(axis=1)返回一个标量时,Pandas会默认将这个值填充到结果DataFrame的所有列中——因为它无法判断你要赋值给哪一列。而返回Series时,Pandas会根据Series的索引(即列名)对应赋值,就不会出现广播重复的问题了。
内容的提问来源于stack exchange,提问作者xa5i
相关产品推荐
相关产品推荐

