【问题标题】:Convert categorical data in pandas dataframe转换熊猫数据框中的分类数据
【发布时间】:2015-11-07 18:52:19
【问题描述】:

我有一个包含此类数据的数据框(列太多):

col1        int64
col2        int64
col3        category
col4        category
col5        category

列看起来像这样:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

我想将列中的所有值转换为整数,如下所示:

[1, 2, 3, 4, 5, 6, 7, 8]

我通过这个解决了一列的问题:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

现在我的数据框中有两列——旧的col3 和新的c,需要删除旧的列。

这是不好的做法。这是可行的,但在我的数据框中有很多列,我不想手动执行。

这个pythonic是怎么做到的?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    只需使用手动匹配:

    dict = {'Non-Travel':0, 'Travel_Rarely':1, 'Travel_Frequently':2}
    
    df['BusinessTravel'] = df['BusinessTravel'].apply(lambda x: dict.get(x))
    

    【讨论】:

      【解决方案2】:
      categorical_columns =['sex','class','deck','alone']
      
      for column in categorical_columns:
           df[column] = pd.factorize(df[column])[0]
      

      Factorize 会将列中每个唯一的分类数据变成一个特定的数字(从 0 到无穷大)。

      【讨论】:

        【解决方案3】:

        你可以使用.replace如下:

        df['col3']=df['col3'].replace(['B', 'C', 'E', 'G', 'H', 'N', 'S', 'W'],[1,2,3,4,5,6,7,8])
        

        .map:

        df['col3']=df['col3'].map({1: 'B', 2: 'C', 3: 'E', 4:'G', 5:'H', 6:'N', 7:'S', 8:'W'})
        

        【讨论】:

          【解决方案4】:

          要将 Dataframe 中的所有列转换为数值数据:

          df2 = df2.apply(lambda x: pd.factorize(x)[0])
          

          【讨论】:

            【解决方案5】:

            这里的答案似乎已经过时了。 Pandas 现在有一个factorize() 函数,你可以创建如下类别:

            df.col.factorize() 
            

            函数签名:

            pandas.factorize(values, sort=False, na_sentinel=- 1, size_hint=None)
            

            【讨论】:

              【解决方案6】:

              你可以像下面这样减少代码:

              f = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),'col3':list('ababb')})
              
              f['col1'] =f['col1'].astype('category').cat.codes
              f['col2'] =f['col2'].astype('category').cat.codes
              f['col3'] =f['col3'].astype('category').cat.codes
              
              f
              

              【讨论】:

                【解决方案7】:

                将分类变量转换为虚拟/指示变量的最简单方法之一是使用 pandas 提供的get_dummies。 例如,我们有数据,其中sex 是一个分类值(男性和女性) 您需要将其转换为虚拟/指标,这是如何做到的。

                tranning_data = pd.read_csv("../titanic/train.csv")
                features = ["Age", "Sex", ] //here sex is catagorical value
                X_train = pd.get_dummies(tranning_data[features])
                print(X_train)
                
                Age Sex_female Sex_male
                20    0          1
                33    1          0
                40    1          0
                22    1          0
                54    0          1

                【讨论】:

                • 这正是我正在寻找的pythonic方式!谢谢!
                【解决方案8】:

                我所做的是,我replace 价值观。

                像这样-

                df['col'].replace(to_replace=['category_1', 'category_2', 'category_3'], value=[1, 2, 3], inplace=True)
                

                这样,如果col 列有分类值,它们将被数值替换。

                【讨论】:

                  【解决方案9】:

                  对于某一列,如果不关心排序,就用这个

                  df['col1_num'] = df['col1'].apply(lambda x: np.where(df['col1'].unique()==x)[0][0])
                  

                  如果您关心排序,请将它们指定为列表并使用它

                  df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))
                  

                  【讨论】:

                    【解决方案10】:

                    为了转换数据集dataC列中的分类数据,我们需要执行以下操作:

                    from sklearn.preprocessing import LabelEncoder 
                    labelencoder= LabelEncoder() #initializing an object of class LabelEncoder
                    data['C'] = labelencoder.fit_transform(data['C']) #fitting and transforming the desired categorical column.
                    

                    【讨论】:

                      【解决方案11】:

                      这里需要转换多个列。所以,我使用的一种方法是..

                      for col_name in df.columns:
                          if(df[col_name].dtype == 'object'):
                              df[col_name]= df[col_name].astype('category')
                              df[col_name] = df[col_name].cat.codes
                      

                      这会将所有字符串/对象类型列转换为分类。然后将代码应用于每种类型的类别。

                      【讨论】:

                        【解决方案12】:

                        这对我有用:

                        pandas.factorize( ['B', 'C', 'D', 'B'] )[0]
                        

                        输出:

                        [0, 1, 2, 0]
                        

                        【讨论】:

                        • 被低估的答案
                        • 很好,比公认的答案简单得多
                        • 我同意,这是一个非常好的和有效的答案
                        • 最佳答案,恕我直言
                        【解决方案13】:

                        @Quickbeam2k1,见下文-

                        dataset=pd.read_csv('Data2.csv')
                        np.set_printoptions(threshold=np.nan)
                        X = dataset.iloc[:,:].values
                        

                        使用 sklearn

                        from sklearn.preprocessing import LabelEncoder
                        labelencoder_X=LabelEncoder()
                        X[:,0] = labelencoder_X.fit_transform(X[:,0])
                        

                        【讨论】:

                        • 你为什么不更正你之前的答案?令人惊讶的是,您现在使用的是 fit_transform 而不是 transform_fit,并更正了 labelencoder 定义。为什么使用iloc[:,:]?这是没用的。图片背后的原因是什么?如果你想证明我和@theGtknerd 你失败了。
                        【解决方案14】:

                        如果您只是担心创建一个额外的列并稍后将其删除,那么首先不要使用新列。

                        dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
                        dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes
                        

                        你已经完成了。现在Categorical.from_array已被弃用,直接使用Categorical

                        dataframe.col3 = pd.Categorical(dataframe.col3).codes
                        

                        如果您还需要从索引到标签的映射,还有更好的方法

                        dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()
                        

                        查看下方

                        print(dataframe)
                        print(mapping_index.get_loc("c"))
                        

                        【讨论】:

                          【解决方案15】:

                          首先,要将分类列转换为其数字代码,您可以使用以下方法更轻松地完成此操作:dataframe['c'].cat.codes
                          此外,可以使用select_dtypes 自动选择数据框中具有特定 dtype 的所有列。这样,您可以在多个自动选择的列上应用上述操作。

                          首先制作一个示例数据框:

                          In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
                          
                          In [76]: df['col2'] = df['col2'].astype('category')
                          
                          In [77]: df['col3'] = df['col3'].astype('category')
                          
                          In [78]: df.dtypes
                          Out[78]:
                          col1       int64
                          col2    category
                          col3    category
                          dtype: object
                          

                          然后通过使用select_dtypes 选择列,然后在每个列上应用.cat.codes,可以得到以下结果:

                          In [80]: cat_columns = df.select_dtypes(['category']).columns
                          
                          In [81]: cat_columns
                          Out[81]: Index([u'col2', u'col3'], dtype='object')
                          
                          In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)
                          
                          In [84]: df
                          Out[84]:
                             col1  col2  col3
                          0     1     0     0
                          1     2     1     1
                          2     3     2     0
                          3     4     0     1
                          4     5     1     1
                          

                          【讨论】:

                          • 有没有一种简单的方法可以得到类别代码和类别字符串值之间的映射?
                          • 你可以使用:df['col2'].cat.categories 例如。
                          • 向任何担心这会将NaN 唯一映射到-1 的人指出
                          • 爱 2 衬里 ;)
                          • 请注意,如果分类是有序的(序数),则cat.codes 返回的数字代码可能不是您在系列中看到的数字代码!
                          猜你喜欢
                          • 2019-08-24
                          • 2022-01-20
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-05-27
                          • 2018-05-15
                          • 1970-01-01
                          • 2021-11-03
                          • 2021-04-03
                          相关资源
                          最近更新 更多