【问题标题】:Pandas: convert categories to numbersPandas:将类别转换为数字
【发布时间】:2023-03-07 15:32:01
【问题描述】:

假设我有一个包含以下国家/地区的数据框:

cc | temp
US | 37.0
CA | 12.0
US | 35.0
AU | 20.0

我知道有一个 pd.get_dummies 函数可以将国家/地区转换为“单热编码”。但是,我希望将它们转换为索引,这样我会得到cc_index = [1,2,1,3]

我假设有一种比使用 get_dummies 和 numpy where 子句更快的方法,如下所示:

[np.where(x) for x in df.cc.get_dummies().values]

在 R 中使用“因子”更容易做到这一点,所以我希望 pandas 也有类似的东西。

【问题讨论】:

  • 你的意思是cc_index = [0,1,0,2]
  • 当然,忘了python 0索引
  • 分类系列或 DataFrame 中的列可能会有所帮助。

标签: python pandas series categorical-data binning


【解决方案1】:

一行代码:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes)

如果您有 list_of_columns,这也适用:

df[list_of_columns] = df[list_of_columns].apply(lambda col:pd.Categorical(col).codes)

此外,如果您想保留您的 NaN 值,您可以应用替换:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes).replace(-1,np.nan)

【讨论】:

    【解决方案2】:

    试试这个,根据频率转换成数字(高频-高数字):

    labels = df[col].value_counts(ascending=True).index.tolist()
    codes = range(1,len(labels)+1)
    df[col].replace(labels,codes,inplace=True)
    

    【讨论】:

      【解决方案3】:

      将任何列更改为数字。它不会创建新列,而只是将值替换为数值数据。

      def characters_to_numb(*args): for arg in args: df[arg] = pd.Categorical(df[arg]) df[arg] = df[arg].cat.codes return df

      【讨论】:

        【解决方案4】:

        如果您使用sklearn 库,您可以使用LabelEncoder。与pd.Categorical 一样,输入字符串在编码之前按字母顺序排序。

        from sklearn.preprocessing import LabelEncoder
        
        LE = LabelEncoder()
        df['code'] = LE.fit_transform(df['cc'])
        
        print(df)
        
           cc  temp  code
        0  US  37.0     2
        1  CA  12.0     1
        2  US  35.0     2
        3  AU  20.0     0
        

        【讨论】:

          【解决方案5】:

          如果您只想将系列转换为整数标识符,可以使用pd.factorize

          请注意,此解决方案与 pd.Categorical 不同,不会按字母顺序排序。所以第一个国家将被分配0。如果你想从1开始,你可以添加一个常量:

          df['code'] = pd.factorize(df['cc'])[0] + 1
          
          print(df)
          
             cc  temp  code
          0  US  37.0     1
          1  CA  12.0     2
          2  US  35.0     1
          3  AU  20.0     3
          

          如果您希望按字母顺序排序,请指定sort=True

          df['code'] = pd.factorize(df['cc'], sort=True)[0] + 1 
          

          【讨论】:

          • 这是否考虑了 NULL 值?
          【解决方案6】:

          首先,更改列的类型:

          df.cc = pd.Categorical(df.cc)
          

          现在数据看起来很相似,但都是分类存储的。获取类别代码:

          df['code'] = df.cc.cat.codes
          

          现在你有:

             cc  temp  code
          0  US  37.0     2
          1  CA  12.0     1
          2  US  35.0     2
          3  AU  20.0     0
          

          如果您不想修改 DataFrame 而只是获取代码:

          df.cc.astype('category').cat.codes
          

          或者使用分类列作为索引:

          df2 = pd.DataFrame(df.temp)
          df2.index = pd.CategoricalIndex(df.cc)
          

          【讨论】:

          • 电话df.cc.cat.codes 似乎已改为df.cc.codes
          • 请注意,如果您有缺失值,它们将被编码为 -1。如果您想避免处理这种情况,您可以先转换为字符串:df.cc.astype('str').astype('category').cat.codes
          • 似乎将NaN 转换为-1
          • @John 它在生产或测试阶段是如何工作的?
          猜你喜欢
          • 1970-01-01
          • 2011-12-10
          • 1970-01-01
          • 2017-02-15
          • 2021-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多