Chuyển đổi dữ liệu phân loại trong khung dữ liệu gấu trúc


102

Tôi có một khung dữ liệu với loại dữ liệu này (quá nhiều cột):

col1        int64
col2        int64
col3        category
col4        category
col5        category

Các cột có vẻ như thế này:

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

Tôi muốn chuyển đổi tất cả giá trị trong các cột thành số nguyên như sau:

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

Tôi đã giải quyết vấn đề này cho một cột bằng cách này:

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

Bây giờ tôi có hai cột trong khung dữ liệu của mình - cũ col3và mới cvà cần loại bỏ các cột cũ.

Đó là thực hành không tốt. Nó hoạt động nhưng trong khung dữ liệu của tôi có nhiều cột và tôi không muốn làm điều đó theo cách thủ công.

Làm thế nào để con trăn này và chỉ khéo léo?

Câu trả lời:


163

Trước tiên, để chuyển đổi một cột Categorical đến mã số của nó, bạn có thể làm dễ dàng hơn này với: dataframe['c'].cat.codes.
Hơn nữa, có thể tự động chọn tất cả các cột với một loại dữ liệu nhất định trong khung dữ liệu bằng cách sử dụng select_dtypes. Bằng cách này, bạn có thể áp dụng thao tác trên trên nhiều cột và được chọn tự động.

Đầu tiên tạo khung dữ liệu mẫu:

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

Sau đó, bằng cách sử dụng select_dtypesđể chọn các cột, và sau đó áp dụng .cat.codestrên từng cột này, bạn có thể nhận được kết quả sau:

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

14
có cách nào dễ dàng để chúng tôi nhận được ánh xạ giữa mã danh mục và các giá trị chuỗi danh mục không?
Allan Ruin

5
Bạn có thể sử dụng: df['col2'].cat.categorieschẳng hạn.
ogrisel

13
Chỉ ra cho bất cứ ai lo ngại rằng điều này sẽ lập bản đồ NaNlà duy nhất để-1
quietContest

2
Yêu 2 lớp lót;)
Jose A

Hãy chú ý rằng nếu phân loại được sắp xếp theo thứ tự (một thứ tự) thì các mã số được trả về cat.codescó thể KHÔNG phải là những mã bạn thấy trong Chuỗi!
paulperry

27

Điều này phù hợp với tôi:

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

Đầu ra:

[0, 1, 2, 0]

20

Nếu mối quan tâm của bạn chỉ là bạn tạo thêm một cột và xóa nó sau đó, chỉ cần sử dụng một cột mới ở vị trí đầu tiên.

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

Bạn xong việc rồi. Hiện Categorical.from_arraykhông được dùng nữa, hãy sử dụng Categoricaltrực tiếp

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

Nếu bạn cũng cần ánh xạ lại từ chỉ mục đến nhãn, thậm chí còn có cách tốt hơn cho cùng một

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

kiểm tra bên dưới

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

11

Ở đây cần phải chuyển đổi nhiều cột. Vì vậy, một cách tiếp cận tôi đã sử dụng là ..

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

Điều này chuyển đổi tất cả các cột kiểu chuỗi / đối tượng thành phân loại. Sau đó áp dụng mã cho từng loại danh mục.


3

Để chuyển đổi dữ liệu phân loại trong cột C của dữ liệu tập dữ liệu , chúng ta cần thực hiện như sau:

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.

1

@ Quickbeam2k1, xem bên dưới -

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

Sử dụng sklearn nhập mô tả hình ảnh ở đây

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

3
Tại sao bạn không sửa câu trả lời trước của mình? Đáng ngạc nhiên là fit_transformbây giờ bạn đang sử dụng thay vì transform_fitvà đã sửa định nghĩa của labelencoder. Tại sao bạn sử dụng iloc[:,:]? điều này là vô ích. Lý do đằng sau hình ảnh là gì? Trong trường hợp bạn muốn chứng minh tôi và @theGtknerd chứng minh bạn đã thất bại.
Quickbeam2k1,

1

Những gì tôi làm là, tôi replacecoi trọng.

Như thế này-

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

Bằng cách này, nếu colcột có các giá trị phân loại, chúng sẽ được thay thế bằng các giá trị số.


0

Đối với một cột nhất định, nếu bạn không quan tâm đến thứ tự, hãy sử dụng

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

Nếu bạn quan tâm đến việc đặt hàng, hãy chỉ định chúng dưới dạng danh sách và sử dụng

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.