在pandas DataFrame中使用np.where或其他广播技术

1 投票
1 回答
1423 浏览
提问于 2025-04-18 07:53

我有一个数据表,里面有几列需要根据不同的条件填充其他列。我写了一个函数,并使用了 df.apply,但是这样做显然非常慢。我想寻求帮助,找一个更快的方法来完成以下操作:

def function(df):
    if pd.isnull(df['criteria_column']) == True:
        return df['return_column']
    else:
        return
df['new_column'] = df.apply(function, axis=1)

我想做类似这样的事情:

 df['new_column'] = np.where(pd.isnull(df['criteria_column'] == True),
                                       df['return_column'], "")

但是这样会出现 ValueError: Could not construct Timestamp from argument <type 'bool'> 的错误。

1 个回答

4

用索引代替apply,这样会快很多:

df["new_column"] = ""
is_null = pd.isnull(df["criteria_column"])
df["new_column"][is_null] = df["return_column"][is_null] # method 1

为了参考,这里还有几种和最后一行做同样事情的方法:

df["new_column"][is_null] = df["return_column"][is_null] # method 1
df["new_column"].loc[is_null] = df.loc["return_column"].loc[is_null] # method 2
df.loc[is_null, "new_column"] = df.loc[is_null, "return_column"] # method 3, thanks @joris

对于那些好奇的人,方法1和方法2是直接访问pandas.Series这个列,并对它们进行选择性的赋值。特别要注意的是,series[is_null]最终还是会调用series.loc[is_null]

最后,方法3是一个方便的方法,它是方法2的简化版,消除了可能的歧义,减少了内存使用,并且允许在连续链式操作后进行赋值。如果你在做复杂的选择链操作,不想产生中间副本,或者想对选择结果进行赋值,这个方法可能会更好。可以查看pandas文档了解更多。

撰写回答