问题描述
我有一个数据框,其中几列缺少数据。在其中一些列中,从“Col_A”到“Col_D”,我想将它们替换为 0。我是这样尝试的:
reduce(lambda x : df.fillna({x : 0},inplace=True),['Col_A','Col_B','Col_C','Col_D'])
但我收到错误消息 <lambda>() takes 1 positional argument but 2 were given
。最终,我将我的解决方案改为简单
df[['Col_A','Col_D']] = df[['Col_A','Col_D']].fillna(0)
但我仍然想知道我之前尝试的解决方案有什么问题。
解决方法
正如评论中所提到的,这是一种实现目标的相当奇怪的方式,有多个与良好编程实践背道而驰的问题
所以从免责声明开始:我不建议这样做,但我只是回答有关函数行为的问题。
排除免责声明,这个可以通过两个小的改变来工作。以下应该工作
reduce(lambda _,x : df.fillna({x : 0},inplace=True),['Col_A','Col_B','Col_C','Col_D'],'fake')
首先请注意,我们让 lambda
接受两个参数,这是 reduce
函数的要求。第一个参数意味着是在上一步应用函数的结果。在这里,由于我们并不真正关心上一步函数的应用结果,而是依赖于 reduce
对全局(reduce 函数)变量 df
的副作用——这个作为这种方法的主要问题——我们将其设为未命名的参数 _
。其次,我们需要一个起点——所谓的初始化器——让 reduce
工作,因为它会用这个值和列表的第一个值调用 lambda 函数作为第一步。如果我们像您一样省略初始化程序,它将从列表的前两个值开始,因此基本上缺少 Col_A
到 fillna
。因此,因此,我们有一个 'fake'
初始化器传递给 reduce
函数(如果不清楚,您可以随意调用它)