【问题标题】:Column dupe renaming in pandas熊猫中的列重复重命名
【发布时间】:2019-05-25 03:07:55
【问题描述】:

我有以下 csv 数据文件:

id,number,id
132605,1,1
132750,2,1

Pandas 目前将其重命名为:

       id number id.1
0  132605      1    1
1  132750      2    1

有没有办法自定义重命名方式?例如,我更喜欢:

           id number id2
0  132605      1    1
1  132750      2    1

【问题讨论】:

    标签: python pandas csv dataframe indexing


    【解决方案1】:

    rename: 使用句号分隔符

    假设重复的列标签是列名称包含句点 (.) 的实例,您可以使用带有 pd.DataFrame.rename 的自定义函数:

    from io import StringIO
    
    file = """id,number,id
    132605,1,1
    132750,2,1"""
    
    def rename_func(x):
        if '.' not in x:
            return x
        name, num = x.split('.')
        return f'{name}{int(num)+1}'
    
    # replace StringIO(file) with 'file.csv'
    df = pd.read_csv(StringIO(file))\
           .rename(columns=rename_func)
    
    print(df)
    
           id  number  id2
    0  132605       1    1
    1  132750       2    1
    

    csv.reader:稳健的解决方案

    使用标准库中的csv 模块可以提供强大的解决方案:

    from collections import defaultdict
    import csv
    
    # replace StringIO(file) with open('file.csv', 'r')
    with StringIO(file) as fin:
        headers = next(csv.reader(fin))
    
    def rename_duplicates(original_cols):
        count = defaultdict(int)
        for x in original_cols:
            count[x] += 1
            yield f'{x}{count[x]}' if count[x] > 1 else x
    
    df.columns = rename_duplicates(headers)
    

    【讨论】:

      【解决方案2】:

      简答

      没有。您无法使用 pandas API 更改添加后缀的方式。

      长答案

      这由pandas.read_csvmangle_dupe_cols 选项处理,目前不支持将其关闭。

      你可以修改pandas.io.parsers._maybe_dedup_names的源代码,但一如既往,不太推荐。

      def _maybe_dedup_names(self, names):
          if self.mangle_dupe_cols:
              names = list(names)  
              # counts = defaultdict(int)
              counts = defaultdict(lambda:1) 
              # So that your duplicated column suffix starts with 2 not 1
              is_potential_mi = _is_potential_multi_index(names)
      
              for i, col in enumerate(names):
                  cur_count = counts[col]
      
                  while cur_count > 0:
                      counts[col] = cur_count + 1
      
                      if is_potential_mi:
                          # col = col[:-1] + ('%s.%d' % (col[-1], cur_count),)
                          col = col[:-1] + ('%s%d' % (col[-1], cur_count),)
                      else:
                          # col = '%s.%d' % (col, cur_count)
                          col = '%s%d' % (col, cur_count)
                      # eliminate '.' from formating
                      cur_count = counts[col]
      
                  names[i] = col
                  counts[col] = cur_count + 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-15
        • 2020-05-03
        • 2017-12-19
        • 2017-10-01
        • 2019-08-25
        • 2018-11-08
        • 2020-07-04
        相关资源
        最近更新 更多