在pandas DataFrame中使用np.where或其他广播技术
我有一个数据表,里面有几列需要根据不同的条件填充其他列。我写了一个函数,并使用了 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文档了解更多。