【问题标题】:Redundant calculation when assigning column values in Pandas在 Pandas 中分配列值时的冗余计算
【发布时间】:2019-11-12 17:28:41
【问题描述】:

我想为数据框中的行子集将“var3”列的值分配给“var2”。见以下 Python 代码

df.loc[df['var1'] == 'x', 'var2'] = df[df['var1'] == 'x']['var3']

var1 上的选择在此语句中发生了两次。有没有办法避免这种冗余计算?

【问题讨论】:

  • 我会推荐使用np.where()
  • @rahlf23 np.where 是如何解决冗余计算的?
  • np.where() 创建一个布尔系列(或过滤器,如果您愿意),然后您的后续参数指定在 TrueFalse 的情况下要分配的值

标签: python pandas performance


【解决方案1】:

IIUC,你应该使用np.where()

df['var2'] = np.where(df['var1']=='x', df['var3'], df['var2'])

【讨论】:

    【解决方案2】:

    您可以预先计算过滤器并将其存储在变量中

    x_filter = df['var1'] == 'x'
    df.loc[x_filter , 'var2'] = df[x_filter]['var3']
    

    这样计算只发生一次

    【讨论】:

    • 谢谢!这是一个很好的解决方案。但我认为@rahlf23 的解决方案更好。
    【解决方案3】:

    我很好奇。两种提议的解决方案都提供了改进,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['var3'], 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), N),
                                      '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)"
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多