我想为数据帧中的行子集将“ var3”列的值分配给“ var2”。请参阅以下Python代码
df.loc[df['var1'] == 'x','var2'] = df[df['var1'] == 'x']['var3']
在此语句中,对var1的选择发生了两次。有办法避免这种多余的计算吗?
我想为数据帧中的行子集将“ var3”列的值分配给“ var2”。请参阅以下Python代码
df.loc[df['var1'] == 'x','var2'] = df[df['var1'] == 'x']['var3']
在此语句中,对var1的选择发生了两次。有办法避免这种多余的计算吗?
您可以预先计算过滤器并将其存储在变量中
x_filter = df['var1'] == 'x'
df.loc[x_filter,'var2'] = df[x_filter]['var3']
这样,计算一次进行一次
, IIUC,您应该使用np.where()
:
df['var2'] = np.where(df['var1']=='x',df['var3'],df['var2'])
,
我很好奇。两种建议的解决方案都提供了改进,其中np.where
解决方案是最快的。尽管这些差异都不会产生很大的问题,但是除非您多次执行此操作或拥有巨大的DataFrame。
import perfplot
import pandas as pd
import numpy as np
def mask_both(df):
df.loc[df['var1'] == 'x','var2'] = df.loc[df['var1'] == 'x','var3']
return df['var2']
def mask_once(df):
m = df['var1'] == 'x'
df.loc[m,'var2'] = df.loc[m,'var3']
return df['var2']
def numpy_where(df):
df['var2'] = np.where(df['var1']=='x',df['var2'])
return df['var2']
perfplot.show(
setup=lambda N: pd.DataFrame({'var1': np.random.choice(['x','y'],N),'var2': np.random.choice(range(100),'var3': np.random.choice(range(100,200),N)}),kernels=[
lambda df: mask_both(df),lambda df: mask_once(df),lambda df: numpy_where(df),],labels=['Mask Twice','Mask Once','Numpy Where'],n_range=[2 ** k for k in range(2,23)],equality_check=np.allclose,xlabel="len(df)"
)