【问题标题】:replace strings in every column with numbers用数字替换每列中的字符串
【发布时间】:2021-08-07 19:19:23
【问题描述】:

这个问题是this question 的扩展。考虑下表中可视化的 pandas DataFrame。

respondent brand engine country aware aware_2 aware_3 age tesst set
0 a volvo p swe 1 0 1 23 set set
1 b volvo None swe 0 0 1 45 set set
2 c bmw p us 0 0 1 56 test test
3 d bmw p us 0 1 1 43 test test
4 e bmw d germany 1 0 1 34 set set
5 f audi d germany 1 0 1 59 set set
6 g volvo d swe 1 0 0 65 test set
7 h audi d swe 1 0 0 78 test set
8 i volvo d us 1 1 1 32 set set

要转换带有字符串条目的列,应该先做一个映射然后pandas.replace()

例如:

mapping = {'set': 1, 'test': 2}
df.replace({'set': mapping, 'tesst': mapping})

这将导致以下 DataFrame(表):

respondent brand engine country aware aware_2 aware_3 age tesst set
0 a volvo p swe 1 0 1 23 1 1
1 b volvo None swe 0 0 1 45 1 1
2 c bmw p us 0 0 1 56 2 2
3 d bmw p us 0 1 1 43 2 2
4 e bmw d germany 1 0 1 34 1 1
5 f audi d germany 1 0 1 59 1 1
6 g volvo d swe 1 0 0 65 2 1
7 h audi d swe 1 0 0 78 2 1
8 i volvo d us 1 1 1 32 1 1

如上所示,最后两列的字符串被替换为代表这些字符串的数字。

那么问题来了: 有没有更快且不那么动手的方法来将所有字符串替换为一个数字?可以自动创建映射(并将其输出到某个地方供人类参考)吗?

使 DataFrame 最终变成这样的东西:

respondent brand engine country aware aware_2 aware_3 age tesst set
0 1 1 1 1 1 0 1 23 1 1
1 2 1 2 1 0 0 1 45 1 1
2 3 2 1 2 0 0 1 56 2 2
3 4 2 1 2 0 1 1 43 2 2
4 5 2 3 3 1 0 1 34 1 1
5 6 3 3 3 1 0 1 59 1 1
6 7 1 3 1 1 0 0 65 2 1
7 8 3 3 1 1 0 0 78 2 1
8 9 1 3 2 1 1 1 32 1 1

也输出:

[{'volvo': 1, 'bmw': 2, 'audi': 3}, {'p': 1, 'None': 2, 'd': 3}, {'swe': 1, 'us': 2, 'germany': 3}]

请注意,地图(dicts)的输出列表不应该是硬编码的,而是由代码生成的。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    从其他答案中,我写了这个函数来解决这个问题:

    import pandas as pd
    
    def convertStringColumnsToNum(data):
        columns = data.columns
        columns_dtypes = data.dtypes
        maps = []
        
        for col_idx in range(0, len(columns)):
            # don't change columns already comprising of numbers
            if(columns_dtypes[col_idx] == 'int64'): # can be extended to more dtypes
                continue
            # inspired from Shivam Roy's answer 
            col = columns[col_idx]
            tmp = pd.Categorical(data[col])
            data[col] = tmp.codes
            maps.append(tmp.categories)
    
        return maps
    

    此函数返回用于将字符串替换为数字代码的mapss。代码是字符串驻留在列表中的索引。此功能有效,但它带有SettingWithCopyWarning

    如果没坏就不要修了,对吧? ;)

    *但是如果有人有办法调整此功能以使警告不再显示,请随时发表评论。然而它有效*耸耸肩* *

    【讨论】:

      【解决方案2】:

      您需要先将列的类型更改为Categorical,然后创建一个新列或用codes 覆盖现有列:

      df['brand'] = pd.Categorical(df['brand'])
      df['brand_codes'] = df['brand'].cat.codes
      

      如果您需要映射:

      dict(enumerate(df['brand'].cat.categories )) #This will work only after you've converted the column to categorical
      

      【讨论】:

        【解决方案3】:

        您可以调整此响应中给出的代码 https://stackoverflow.com/a/39989896/15320403(在您链接的帖子内)为您选择的每一列生成映射并按照您的建议应用替换

        all_brands = df.brand.unique()
        brand_dic = dict(zip(all_brands, range(len(all_brands))))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-06
          • 2013-05-01
          • 2021-10-08
          • 1970-01-01
          • 2021-12-25
          • 2021-05-22
          • 2013-05-03
          • 2015-09-25
          相关资源
          最近更新 更多