我正在尝试使用pandas pd.DataFrame.where
,如下所示:
df.where(cond=mask, other=df.applymap(f))
其中f
是用户定义的函数,用于对单个单元格进行操作。我不能使用other=f
,因为它似乎产生了不同的结果。
所以基本上我想在DataFrame的所有单元格中评估函数f
,它不满足我作为mask
给出的某些条件。
使用where
的上述用法效率不高,因为它会立即为整个DataFrame f
评估df
,而我只需要在DataFrame的某些条目中对其进行评估,与整个DataFrame相比,有时可能只有很少的特定条目。
是否有其他用法/方法可以更有效地解决这种一般情况?
答案 0 :(得分:1)
正如您所说,在df.applymap(f)
之前评估df.where()
。我很确定df.where()
是一个快速的功能,并不是这里的瓶颈。
df.applymap(f)
更有可能效率低下,并且通常以矢量化的方式更快地执行f
。话虽如此,如果您确实认为这是不可能的,并且f
本身很慢,您可以修改f
,以便在您的掩码False
的任何地方保持输入不变。这很可能会非常缓慢,你绝对宁愿尝试向量化f。
如果你真的必须按元素进行,你可以使用NumPy数组:
result = df.values
for (i,j) in np.where(mask):
result[i,j] = f(result[i,j])
对此使用NumPy数组至关重要,而不是数据框中的.iloc
或.loc
,因为对pandas数据框建立索引的速度很慢。
您可以将此速度与.applymap
进行比较;对于相同的操作,我不认为.applymap
比简单的for循环快得多(如果有的话),因为所有的pandas都在Python中运行它自己的for循环(也许是Cython?但即便如此只节省开销,而不是功能本身)。这与'正确'矢量化不同,因为矢量运算是用C实现的。