Python 另一种有效的熊猫保护方法

Python 另一种有效的熊猫保护方法,python,pandas,Python,Pandas,我正在尝试使用pandas pd.DataFrame.where,如下所示: df.where(cond=mask, other=df.applymap(f)) 其中f是一个用户定义的函数,用于在单个单元格上操作。我不能使用other=f,因为它似乎会产生不同的结果 所以基本上我想在数据帧的所有单元上计算函数f,它不满足一些条件,我把这些条件作为掩码 上面使用where的用法不是很有效,因为它会立即为整个数据帧df计算f,而我只需要在数据帧的某些条目上计算f,与整个数据帧相比,这些条目有时可能

我正在尝试使用pandas pd.DataFrame.where,如下所示:

df.where(cond=mask, other=df.applymap(f))
其中f是一个用户定义的函数,用于在单个单元格上操作。我不能使用other=f,因为它似乎会产生不同的结果

所以基本上我想在数据帧的所有单元上计算函数f,它不满足一些条件,我把这些条件作为掩码

上面使用where的用法不是很有效,因为它会立即为整个数据帧df计算f,而我只需要在数据帧的某些条目上计算f,与整个数据帧相比,这些条目有时可能很少

在解决这种一般情况时,是否有更有效的替代用法/方法

正如您正确指出的,df.applymapf在df.where之前进行评估。我相当肯定df.where是一个快速函数,不是这里的瓶颈

更有可能的是df.applymapf效率低下,通常有一种更快的方法以矢量化的方式执行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非常重要,因为索引数据帧的速度很慢


您可以将其速度与.applymap;对于相同的操作,我不认为applymap比简单的for循环要快得多,因为pandas所做的只是在Python中运行自己的for循环,也许是Cython?但即使这样,也只能节省开销,而不能节省函数本身。这与“适当”的矢量化不同,因为矢量运算是在C中实现的。

能否提供样本数据和函数定义?能否修改f?如果没有,df.applymaplambda x:fx If cond else x应该在不需要where的情况下执行。您可以修改f以保持输入不变,无论您的掩码为False,这正是我要查找的。如何实现这一点?我实际上是在假设布尔掩码只取决于数据的值的情况下做出这一陈述的,事实可能并非如此。如果事实并非如此,那么不使用一些荒谬的全局变量是不可能的。这是因为.applymap只将值而不是索引传递到f中。