【问题标题】:Mapping values inside pandas column熊猫列内的映射值
【发布时间】:2019-01-02 18:24:14
【问题描述】:

我使用下面的代码将 S 列中的 2 个值映射为 0,但它不起作用。关于如何解决这个问题的任何建议? 注意:我想在地图内实现一个外部函数。

 df = pd.DataFrame({
   'Age': [30,40,50,60,70,80],
   'Sex': ['F','M','M','F','M','F'],
   'S'  : [1,1,2,2,1,2]
 })
 def app(value):
     for n in df['S']:
         if n == 1:
             return 1
         if n == 2:
             return 0
 df["S"] = df.S.map(app)

【问题讨论】:

    标签: python pandas dictionary data-science


    【解决方案1】:

    你可以这样做:

    import numpy as np
    
    df['S'] = np.where(df['S'] == 2, 0, df['S'])
    

    【讨论】:

      【解决方案2】:
      >>>df = pd.DataFrame({'Age':[30,40,50,60,70,80],'Sex': 
       ['F','M','M','F','M','F'],'S': 
       [1,1,2,2,1,2]})
      
      
      >>> def app(value):
              return 1 if value == 1 else 0 
          # or app = lambda value : 1 if value == 1 else 0
      
      >>> df["S"] = df["S"].map(app)
      
      >>> df 
         Age  S Sex
            Age  S Sex
         0   30  1   F
         1   40  1   M
         2   50  0   M
         3   60  0   F
         4   70  1   M
         5   80  0   F
      

      【讨论】:

        【解决方案3】:

        不要使用 apply,只需使用 loc 来分配值:

        df.loc[df.S.eq(2), 'S'] = 0
        
           Age Sex  S
        0   30   F  1
        1   40   M  1
        2   50   M  0
        3   60   F  0
        4   70   M  1
        5   80   F  0
        

        如果您需要更高性能的选项,请使用 np.select。这也更具可扩展性,因为您可以随时添加更多条件:

        df['S'] = np.select([df.S.eq(2)], [0], 1)
        

        【讨论】:

          【解决方案4】:

          使用eq 创建一个布尔系列并将该布尔系列转换为astype 的int:

          df['S'] = df['S'].eq(1).astype(int)
          

          df['S'] = (df['S'] == 1).astype(int)
          

          输出:

             Age Sex  S
          0   30   F  1
          1   40   M  1
          2   50   M  0
          3   60   F  0
          4   70   M  1
          5   80   F  0
          

          【讨论】:

          • 嗯,这比通过loc分配要快得多
          • @user3483203 你可以试试 mask,应该更快:-) df.S.mask(df.S>1,0)
          • 是的,快得多,我需要使用mask more :D
          【解决方案5】:

          使用矢量化 numpy 操作:

          df['S'] = np.abs(df['S'] - 2)
          

          并在面试和 SO 答案中脱颖而出 :)

          【讨论】:

            【解决方案6】:

            您可以按如下方式使用 .replace: df["S"] = df["S"].replace([2], 0) 这将在一行中将所有 2 个值替换为 0

            【讨论】:

              【解决方案7】:

              如果您只想更改等于 2 的值,可以使用pd.DataFrame.loc

              df.loc[df['S'] == 0, 'S'] = 0
              

              不推荐pd.Series.apply,这只是一个隐蔽、低效的循环。

              【讨论】:

                【解决方案8】:

                您已经接近了,但您需要进行一些更正。既然要使用函数,请删除for 循环并将n 替换为value。此外,请使用 apply 而不是 mapApply 一次对整个列进行操作。请参阅此answer,了解如何正确使用apply vs applymap vs map

                def app(value):
                    if value == 1:
                        return 1
                    elif value == 2:
                        return 0
                df['S'] = df.S.apply(app)
                   Age Sex  S
                0   30   F  1
                1   40   M  1
                2   50   M  0
                3   60   F  0
                4   70   M  1
                5   80   F  0
                

                【讨论】:

                  猜你喜欢
                  • 2019-07-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-05-03
                  • 2021-09-03
                  • 2018-07-23
                  • 2018-06-05
                  • 2020-07-12
                  • 1970-01-01
                  相关资源
                  最近更新 更多