【问题标题】:pandas map one column to the combination of two columns熊猫将一列映射到两列的组合
【发布时间】:2019-05-19 09:00:15
【问题描述】:

我正在使用一个看起来像这样的DataFrame

List    Numb    Name
1       1       one
1       2       two
2       3       three
4       4       four
3       5       five

我正在尝试计算以下输出。

List    Numb    Name
one     1       one
one     2       two
two     3       three
four    4       four
three   5       five

在我目前的方法中,我尝试遍历列,然后用第三列的内容替换值。

例如,如果List[0][1] 等于Numb[1][1],则将List[0][1] 列替换为'one'。

我怎样才能使这样的迭代工作,或者在根本不显式迭代的情况下解决问题?

【问题讨论】:

  • 如果这与pandas有关,您应该添加适当的标签。
  • @N.P.那是错误的。他希望在同一个 df 上合并或在 Excel 术语中进行索引匹配
  • 对不起,错过了,你是说这个吗?:df['List'] = [df.loc[df['Numb'] == i, 'Name'] for i in df['List']]
  • 我认为我编辑的标题比原来的要好,因为这个问题实际上与迭代无关。但是,“组合”这个词相当模糊,所以任何能想到更好标题的人都欢迎编辑问题。

标签: python arrays pandas dataframe


【解决方案1】:

使用地图

df['List'] = df['List'].map(df.set_index('Numb')['Name'])


    List    Numb    Name
0   one     1   one
1   one     2   two
2   two     3   three
3   four    4   four
4   three   5   five

【讨论】:

    【解决方案2】:

    创建一个字典来帮助你怎么样?

    import pandas as pd
    
    df = pd.DataFrame({'List': [1, 1, 2, 4, 3], 'Numb': [1, 2, 3, 4, 5], 'Name': ['one', 'two', 'three', 'four', 'five']})
    
    d = dict(zip(df['Numb'], df['Name']))
    df = df.replace({'List': d})
    

    【讨论】:

      【解决方案3】:

      您可以在一行中完成此操作。看起来你想将你的数据框加入到自身上:

      df.rename(columns={"List": "List_numb"}).join(df.set_index("Numb")["Name"].to_frame("List"), on="List_numb")[["List", "Numb", "Name"]]
      

      【讨论】:

        【解决方案4】:

        使用set_index,然后使用reindex:

        df['List'] = df.set_index('Numb')['Name'].reindex(df['List']).values
        
        print(df)
        
            List  Numb   Name
        0    one     1    one
        1    one     2    two
        2    two     3  three
        3   four     4   four
        4  three     5   five
        

        【讨论】:

          【解决方案5】:
          import pandas as pd
          
          df = pd.DataFrame({
                  'List': [1,1,2,4,3],
                  'Numb': [1,2,3,4,5],
                  'Name':['one','two','three','four','five']
                  })
          
          dfnew = pd.merge(df, df, how='inner', left_on=['List'], right_on=['Numb'])
          dfnew = dfnew.rename({'List_x': 'List', 'Numb_x': 'Numb', 'Name_y': 'Name'}, axis='columns')
          dfnew = dfnew[['List','Numb','Name']]
          dfnew['List'] = dfnew['Name']
          
          print (dfnew)
          #    List  Numb   Name
          #0    one     1    one
          #1    one     2    one
          #2    two     3    two
          #3   four     4   four
          #4  three     5  three
          

          【讨论】:

            【解决方案6】:

            类似于Vaishali's answer 的答案,但显式构建Series 似乎要快一些。

            df['List'] = df['List'].map(pd.Series(df['Name'].values, df['Numb']))
            

            Timings(Numb 和 Name 列有唯一值的虚拟数据,到目前为止我只包括了三个最快的解决方案):

            >>> df                                                                                                                 
                  List  Numb        Name
            0        1     1       one_0
            1        1     2       two_1
            2        2     3     three_2
            3        4     4      four_3
            4        3     5      five_4
            ...    ...   ...         ...
            4995     1  4996    one_4995
            4996     1  4997    two_4996
            4997     2  4998  three_4997
            4998     4  4999   four_4998
            4999     3  5000   five_4999
            
            [5000 rows x 3 columns]
            
            # Timings (i5-6200U CPU @ 2.30GHz, but only relative times are interesting)
            >>> %timeit df.set_index('Numb')['Name'].reindex(df['List']).values # jpp                                              
            1.14 ms ± 3.36 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
            >>> %timeit df['List'].map(df.set_index('Numb')['Name']) # Vaishali                                                    
            1.04 ms ± 7.13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
            >>> %timeit df['List'].map(pd.Series(df['Name'].values, df['Numb'])) # timgeb                                                   
            437 µs ± 3.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-09-03
              • 2021-04-30
              • 1970-01-01
              • 2019-09-28
              • 2019-01-02
              • 2021-11-19
              • 1970-01-01
              • 2021-05-03
              相关资源
              最近更新 更多