【问题标题】:Pythonic way to simplify multiply 2 pandas columns with condition用条件简化乘以 2 个 pandas 列的 Pythonic 方法
【发布时间】:2016-04-27 10:10:48
【问题描述】:

我正在寻找一种方法来简化以下示例:

self.df[TARGET_NAME] = self.df.apply(lambda row: 1 if row['WINNER'] == 1 and row['WINNER_OVER_2_5'] == 1 else 0, axis=1)

喜欢:

self.df[TARGET_NAME] = self.df[(self.df.WINNER == 1)] & self.df[(self.df.WINNER_OVER_2_5 == 1)] # 不是不正确

还有更复杂的如下

df["PROFIT"] = np.where((df[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"] == 0),
                                  df['MATCH_HOME'] * df['HOME_STAKE'],
                                  np.where((dfml[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"] == 1),
                                           df['MATCH_DRAW'] * df['DRAW_STAKE'],
                                           np.where((df[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"] == 2),
                                                    df['MATCH_AWAY'] * df['AWAY_STAKE'],
                                                    -0))).astype(float)

【问题讨论】:

  • IIUC 你可以使用df['TARGET_NAME'] = np.where((df.WINNER.isin([1]) & df.WINNER_OVER_2_5.isin([1])),1,0)

标签: python python-2.7 numpy pandas


【解决方案1】:

我正在寻找一种方法来简化以下示例:

我猜您正在寻找更简单的语法。这个怎么样:

df['MATCH'] = matches(df, values=(0,1), WINNER=1, WINNER_OVER_2_5=1)

请注意,values= 是可选的,可以接受任何 tuple(false-value, true-value),默认为 (False, True)

要到达那里需要一点魔法。本质上,这通过链接条件并将结果转换为指定的值来构建真值表。它最终会和你的lambda 做同样的事情,只是以一种通用的方式。

def matches(df, values=None, **kwargs):
    values = values or (False, True)
    flt = None
    for var, value in kwargs.iteritems():
        t = (df[var] == value)
        flt = (flt & t) if flt is not None else t
    flt = flt.apply(lambda t : values[t])
    return flt

【讨论】:

    【解决方案2】:

    也许你可以试试布尔属性

    df= pd.DataFrame({'a':[1,0,1,0],'b' :[1,1,0,np.nan]})
    
    df['NEW']= ((df['a']==1 ) &  (df['b']==1)).astype(int).fillna(0)
    

    【讨论】:

      【解决方案3】:

      IIUC 你可以使用isin:

      print df
         WINNER  WINNER_OVER_2_5
      0       1                0
      1       1                1
      2       0                2
      
      df['TARGET_NAME'] = np.where((df.WINNER.isin([1]) & df.WINNER_OVER_2_5.isin([1])),1,0)
      print df
         WINNER  WINNER_OVER_2_5  TARGET_NAME
      0       1                0            0
      1       1                1            1
      2       0                2            0
      

      编辑(未经测试,因为没有数据):

      df["PROFIT"] = np.where((df[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"].isin([0])),
                                        df['MATCH_HOME'] * df['HOME_STAKE'],
                                        np.where((dfml[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"].isin([1])),
                                                 df['MATCH_DRAW'] * df['DRAW_STAKE'],
                                                 np.where((df[TARGET_NAME] == df["PREDICTED"]) & (df["PREDICTED"].isin([2])),
                                                          df['MATCH_AWAY'] * df['AWAY_STAKE'],
                                                          0))).astype(float)
      

      【讨论】:

      • 谢谢!如我所见,上面的第二个示例已经简化了吗? :)
      • 对于一些数据集和你的例子#1,catch ValueError: Length of values does not match length of index
      • 同一个df,我不明白为什么会出现问题
      猜你喜欢
      • 2022-08-19
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 2019-03-28
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      相关资源
      最近更新 更多