সাইকিট-শিখায় একাধিক কলামে লেবেল এনকোডিং


216

আমি স্ট্রিং লেবেলের LabelEncoderএকটি পান্ডাকে এনকোড করতে সাইকিট-লার্নস ব্যবহার করার চেষ্টা করছি DataFrame। যেহেতু ডেটাফ্রেমে অনেকগুলি (50+) কলাম রয়েছে, তাই আমি LabelEncoderপ্রতিটি কলামের জন্য একটি অবজেক্ট তৈরি করা এড়াতে চাই ; আমি বরং একটি বড় LabelEncoderঅবজেক্ট থাকব যা আমার সমস্ত ডেটা কলাম জুড়ে কাজ করে।

সমগ্র নিক্ষেপ DataFrameমধ্যে LabelEncoderত্রুটি নিচে সৃষ্টি করে। দয়া করে মনে রাখবেন যে আমি এখানে ডামি ডেটা ব্যবহার করছি; বাস্তবে আমি স্ট্রিং লেবেলযুক্ত ডেটার প্রায় 50 টি কলামের সাথে ডিল করছি, সুতরাং এমন একটি সমাধানের দরকার যা কোনও কলামের নাম দিয়ে রেফারেন্স না করে।

import pandas
from sklearn import preprocessing 

df = pandas.DataFrame({
    'pets': ['cat', 'dog', 'cat', 'monkey', 'dog', 'dog'], 
    'owner': ['Champ', 'Ron', 'Brick', 'Champ', 'Veronica', 'Ron'], 
    'location': ['San_Diego', 'New_York', 'New_York', 'San_Diego', 'San_Diego', 
                 'New_York']
})

le = preprocessing.LabelEncoder()

le.fit(df)

ট্রেসব্যাক (সর্বশেষতম কলটি শেষ): ফাইল "", লাইন 1, ফাইলের মধ্যে "/ ব্যবহারকারী / বাবলিন / অ্যানাকোন্ডা / লিবি /পিথন 2.7/site-packages/sklearn/preprocessing/label.py", 103 লাইন, ফিট y = কলাম_অর_ড (y, সতর্কতা = সত্য) ফাইল "/ ব্যবহারকারীর / বাল্বিন / অ্যানাকোন্ডা / লিবি / স্পাইথন 2.7/site-packages/sklearn/utils/uthorization.py", 306 লাইন, কলাম_অর_আর মান বাড়ান ("খারাপ ইনপুট আকার { 0} "। ফর্ম্যাট (আকৃতি) মান মান: খারাপ ইনপুট শেপ (6, 3)

এই সমস্যাটি কীভাবে পেতে পারে সে সম্পর্কে কোনও চিন্তাভাবনা?


আপনি কেন এটি করার চেষ্টা করছেন?
ফ্রেড ফু

dataframeস্ট্রিং ডেটার একাধিক কলামকে এনকোডিং সহজ করতে । আমি এনকোডিং অবজেক্ট (গুলি) এ টিক দিচ্ছি, সুতরাং 50 টি পৃথক বস্তুর আচার / আনপিকেল করা এড়াতে চাই। এছাড়াও, আমি আশ্চর্য হই যে এনকোডারটি ডেটা সরল করার কোনও উপায় আছে, অর্থাত্ প্রতিটি কলামে ভেরিয়েবলের প্রতিটি অনন্য সংমিশ্রণের জন্য একটি শনাক্তকারী দিয়ে কেবল একটি সারি ফিরে আসা।
ব্রায়ান

replaceপদ্ধতিতে অভিধানের একটি অভিধান পাস করে পান্ডে এগুলি করার সহজ উপায় রয়েছে । নীচে এই উত্তরটি দেখুন
টেড পেট্রো

উত্তর:


451

আপনি সহজেই এটি করতে পারেন যদিও,

df.apply(LabelEncoder().fit_transform)

EDIT2:

সাইকিট-লার্ন 0.20 এ, প্রস্তাবিত উপায়

OneHotEncoder().fit_transform(df)

যেমন OneHotEncoder এখন স্ট্রিং ইনপুট সমর্থন করে। ওয়ানহটইনকোডারকে কেবলমাত্র নির্দিষ্ট কলামগুলিতে প্রয়োগ করা কলম ট্রান্সফরমার দিয়ে সম্ভব।

সম্পাদনা করুন:

যেহেতু এই উত্তরটি এক বছরেরও বেশি সময় পূর্বে, এবং অনেকগুলি উত্সাহ উত্পন্ন করেছে (একটি অনুগ্রহ সহ), আমার সম্ভবত এটি আরও বাড়ানো উচিত।

ইনভার্স_টান্সফর্ম এবং ট্রান্সফর্মের জন্য আপনাকে কিছুটা হ্যাক করতে হবে।

from collections import defaultdict
d = defaultdict(LabelEncoder)

এটির সাহায্যে আপনি এখন LabelEncoderঅভিধান হিসাবে সমস্ত কলাম সংরক্ষণ করতে পারেন ।

# Encoding the variable
fit = df.apply(lambda x: d[x.name].fit_transform(x))

# Inverse the encoded
fit.apply(lambda x: d[x.name].inverse_transform(x))

# Using the dictionary to label future data
df.apply(lambda x: d[x.name].transform(x))

1
এটি আশ্চর্যজনক তবে এই ক্ষেত্রে আমরা কীভাবে বিপরীত রূপান্তর প্রয়োগ করতে পারি?
সুপ্রিথ মেকা

10
তবে যদি আমি এই সমাধানটি পাইপলাইনে যেমন পৃথক ফিট এবং ট্রান্সফর্ম (ট্রেনে ফিট করে, এবং তারপরে টেস্ট-সেট -> শিখানো অভিধানটি পুনরায় ব্যবহার করতে চান) ব্যবহার করতে চান তবে এটি কি সমর্থন করে df.apply(LabelEncoder().fit_transform)?
জর্জি হিলার

2
এর পরিবর্তে কীভাবে এটি তৈরি করা যায় LabelBinarizerএবং পরীক্ষার সেটটির জন্য অভিধানটি পুনরায় ব্যবহার করা যায়? আমি চেষ্টা d = defaultdict(LabelBinarizer)এবং তারপর fit = df.apply(lambda x: d[x.name].fit_transform(x))কিন্তু একটি ব্যতিক্রম উত্থাপিত হয়: Exception: Data must be 1-dimensional। আমি নিশ্চিত না যে আমি কীভাবে ফলাফল ডেটা ফ্রেমটি দেখতে প্রত্যাশা করব ... সম্ভবত প্রতিটি কলামে বাইনারিযুক্ত ভেক্টর রাখা উচিত।
কুলুলু

4
সুন্দর সমাধান। শুধুমাত্র নির্দিষ্ট কলামে কীভাবে রূপান্তর করা যায়?
স্টেনলিটউ

1
যদি আমি একটি কলামের জন্য এনকোড যুক্তিকে বিপরীত করতে চাই তবে আমি কীভাবে এটি করব?
ইব ডি

95

লারসম্যান দ্বারা উল্লিখিত হিসাবে, LabelEncoder () আর্গুমেন্ট হিসাবে কেবল 1-d অ্যারে নেয় । এটি বলেছিল, আপনার নিজের লেবেল এনকোডার যা আপনার পছন্দের একাধিক কলামে পরিচালনা করে, এটি রোল করা বেশ সহজ এবং রূপান্তরিত ডেটাফ্রেমটি ফেরত দেয়। এখানে আমার কোড জাক স্টুয়ার্ট এর চমৎকার ব্লগ পোস্টে পাওয়া উপর ভিত্তি করা হয় এখানে

একটি কাস্টম এনকোডার তৈরি করা হচ্ছে কেবল একটি বর্গ তৈরি জড়িত যে সাড়া fit(), transform()এবং fit_transform()পদ্ধতি। আপনার ক্ষেত্রে, একটি ভাল শুরু হতে পারে এরকম কিছু হতে পারে:

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline

# Create some toy data in a Pandas dataframe
fruit_data = pd.DataFrame({
    'fruit':  ['apple','orange','pear','orange'],
    'color':  ['red','orange','green','green'],
    'weight': [5,6,3,4]
})

class MultiColumnLabelEncoder:
    def __init__(self,columns = None):
        self.columns = columns # array of column names to encode

    def fit(self,X,y=None):
        return self # not relevant here

    def transform(self,X):
        '''
        Transforms columns of X specified in self.columns using
        LabelEncoder(). If no columns specified, transforms all
        columns in X.
        '''
        output = X.copy()
        if self.columns is not None:
            for col in self.columns:
                output[col] = LabelEncoder().fit_transform(output[col])
        else:
            for colname,col in output.iteritems():
                output[colname] = LabelEncoder().fit_transform(col)
        return output

    def fit_transform(self,X,y=None):
        return self.fit(X,y).transform(X)

ধরা যাক আমরা সংখ্যার অ্যাট্রিবিউটকে একা রেখেই আমাদের দুটি শ্রেণীবদ্ধ বৈশিষ্ট্য ( fruitএবং color) এনকোড করতে চাই weight। আমরা নিম্নলিখিত হিসাবে এটি করতে পারে:

MultiColumnLabelEncoder(columns = ['fruit','color']).fit_transform(fruit_data)

যা fruit_dataথেকে আমাদের ডেটাসেটকে রূপান্তর করে

এখানে চিত্র বর্ণনা লিখুন প্রতি

এখানে চিত্র বর্ণনা লিখুন

সম্পূর্ণরূপে শ্রেণিবদ্ধ ভেরিয়েবল সমন্বিত একটি ডেটাফ্রেম পাস করা এবং columnsপ্যারামিটার বাদ দেওয়া প্রতিটি কলামকে এনকোড করা হবে (যা আমি বিশ্বাস করি আপনি মূলত যা খুঁজছিলেন):

MultiColumnLabelEncoder().fit_transform(fruit_data.drop('weight',axis=1))

এই রূপান্তর

এখানে চিত্র বর্ণনা লিখুন প্রতি

এখানে চিত্র বর্ণনা লিখুন

মনে রাখবেন যে এটি ইতিমধ্যে সংখ্যাসূচক বৈশিষ্ট্যগুলি এনকোড করার চেষ্টা করার সময় এটি শ্বাসরোধ করবে (যদি আপনি চান তবে এটি পরিচালনা করতে কিছু কোড যুক্ত করুন)।

এ সম্পর্কে আরও একটি দুর্দান্ত বৈশিষ্ট্য হ'ল আমরা পাইপলাইনে এই কাস্টম ট্রান্সফর্মারটি ব্যবহার করতে পারি:

encoding_pipeline = Pipeline([
    ('encoding',MultiColumnLabelEncoder(columns=['fruit','color']))
    # add more pipeline steps as needed
])
encoding_pipeline.fit_transform(fruit_data)

2
কেবলমাত্র উপলব্ধ ডেটা বোঝা গেল যে একটি কমলা রঙের সবুজ। উফ। ;)
প্রাইসহার্ডম্যান 21

5
এটি একবারে ডেটা ট্রান্সফর্ম করার একটি ভাল উপায় তবে আমি যদি কোনও বৈধতা সেটটিতে এই রূপান্তরটি পুনরায় ব্যবহার করতে চাই তবে কী হয়। আপনাকে আবার ফিট-ট্রান্সফর্ম করতে হবে এবং আমার নতুন ডেটা সেট হিসাবে সমস্ত ভেরিয়েবলের জন্য সমস্ত বিভাগ না থাকায় সমস্যা দেখা দিতে পারে। উদাহরণস্বরূপ, বলুন যে সবুজ রঙ আমার নতুন ডেটা সেটে প্রদর্শিত হবে না। এটি এনকোডিংকে বিশৃঙ্খলা করবে।
বেন

3
@ বেনের সাথে একমত এটি আসলে পদ্ধতির নামগুলি ছাড়াই স্কলারনকে নকল করে না। আপনি যদি এটি একটি পাইপলাইনে রাখার চেষ্টা করেন তবে এটি কার্যকর হবে না
Tgsmith61591

3
লেবেল এনকোডিংটি ট্রেন এবং পরীক্ষা উভয় সেট জুড়েই সুসংগত রয়েছে তা নিশ্চিত করার জন্য, আপনি আপনার পুরো ডেটাসেটে (ট্রেন + পরীক্ষা) এনকোডিংটি সম্পাদন করতে চান। এটি ট্রেন ও পরীক্ষায় বিভক্ত করার আগেই করা যেতে পারে, বা আপনি তাদের একত্রিত করতে, এনকোডিংটি সম্পাদন করতে এবং এগুলি আবার বিভক্ত করতে পারেন।
প্রাইসহার্ডম্যান 21

2
বিপরীত যাচ্ছে কিভাবে? আসল ফিরে ডিকোডিং?
ব্যবহারকারী 702846

18

যেহেতু সাইকিট-শিখুন 0.20 আপনি ব্যবহার করতে পারেন sklearn.compose.ColumnTransformerএবং sklearn.preprocessing.OneHotEncoder:

আপনার যদি কেবল শ্রেণিবদ্ধ ভেরিয়েবল থাকে তবে OneHotEncoderসরাসরি:

from sklearn.preprocessing import OneHotEncoder

OneHotEncoder(handle_unknown='ignore').fit_transform(df)

আপনার যদি বিজাতীয়ভাবে টাইপ করা বৈশিষ্ট্যগুলি রয়েছে:

from sklearn.compose import make_column_transformer
from sklearn.preprocessing import RobustScaler
from sklearn.preprocessing import OneHotEncoder

categorical_columns = ['pets', 'owner', 'location']
numerical_columns = ['age', 'weigth', 'height']
column_trans = make_column_transformer(
    (categorical_columns, OneHotEncoder(handle_unknown='ignore'),
    (numerical_columns, RobustScaler())
column_trans.fit_transform(df)

ডকুমেন্টেশন আরো বিকল্পগুলি: http://scikit-learn.org/stable/modules/compose.html#columntransformer-for-heterogeneous-data


inverse_transform()যদিও কলামট্রান্সফর্মারটিতে সমর্থিত নয়। কমপক্ষে, এই মুহুর্তের জন্য নয়: github.com/scikit-learn/scikit-learn/issues/11463 । এটি আমার আবেদনের জন্য একটি বড় অসুবিধা এবং সম্ভবত অন্যদের জন্যও হবে।
স্যান্ডার ভ্যান্ডেন হউতে

16

আমাদের কোনও লেবেল এনকোডার দরকার নেই।

আপনি কলামগুলি বিভাগগুলিতে রূপান্তর করতে পারেন এবং তারপরে কোডগুলি পেতে পারেন। আমি প্রতিটি কলামে এই প্রক্রিয়াটি প্রয়োগ করতে নীচে অভিধানের বোধগম্যতা ব্যবহার করেছি এবং ফলাফলটিকে একই আকারের ডেটাফ্রেমে অভিন্ন সূচক এবং কলামের নাম দিয়ে আবার মোড়াতে চাই।

>>> pd.DataFrame({col: df[col].astype('category').cat.codes for col in df}, index=df.index)
   location  owner  pets
0         1      1     0
1         0      2     1
2         0      0     0
3         1      1     2
4         1      3     1
5         0      2     1

একটি ম্যাপিং অভিধান তৈরি করতে, আপনি কেবল অভিধান বোধগম্যতা ব্যবহার করে বিভাগগুলি গণনা করতে পারেন:

>>> {col: {n: cat for n, cat in enumerate(df[col].astype('category').cat.categories)} 
     for col in df}

{'location': {0: 'New_York', 1: 'San_Diego'},
 'owner': {0: 'Brick', 1: 'Champ', 2: 'Ron', 3: 'Veronica'},
 'pets': {0: 'cat', 1: 'dog', 2: 'monkey'}}

যদি আমি কোনও কলামের জন্য ফিরে যেতে (বিপরীত) করতে চাই (উদাহরণস্বরূপ টার্গেট ভেরিয়েবল: ওয়াই) আমি কীভাবে এটি করব?
ইব ডি

9

এটি সরাসরি আপনার প্রশ্নের উত্তর দেয় না (যার জন্য নাপুটিপুলু জোন এবং প্রাইসহার্ডম্যানের দুর্দান্ত উত্তর রয়েছে)

তবে কয়েকটি শ্রেণিবদ্ধকরণের কাজ ইত্যাদির উদ্দেশ্যে আপনি ব্যবহার করতে পারেন

pandas.get_dummies(input_df) 

এটি বিভাগীয় ডেটা সহ ডেটাফ্রেম ইনপুট করতে পারে এবং বাইনারি মান সহ একটি ডেটা ফ্রেম ফিরিয়ে আনতে পারে। পরিবর্তনশীল মানগুলি ফলাফল ডেটা ফ্রেমের কলামের নামগুলিতে এনকোড করা হয়। অধিক


6

ধরে নিই যে আপনি কেবল এমন কোনও sklearn.preprocessing.LabelEncoder()জিনিস পাওয়ার চেষ্টা করছেন যা আপনার কলামগুলিকে উপস্থাপন করতে ব্যবহার করা যেতে পারে, আপনাকে যা করতে হবে তা হ'ল:

le.fit(df.columns)

উপরের কোডটিতে আপনার প্রতিটি কলামের সাথে সম্পর্কিত একটি অনন্য নম্বর থাকবে। 1 ম্যাপিং: আরো সঠিকভাবে, আপনি একটি 1 থাকবে df.columnsকরার le.transform(df.columns.get_values())। একটি কলামের এনকোডিং পেতে, কেবল এটি পাস করুন le.transform(...)। উদাহরণ হিসাবে, নিম্নলিখিত প্রতিটি কলামের জন্য এনকোডিং পাবেন:

le.transform(df.columns.get_values())

ধরে নিই যে আপনি sklearn.preprocessing.LabelEncoder()আপনার সমস্ত সারি লেবেলের জন্য একটি অবজেক্ট তৈরি করতে চান আপনি নিম্নলিখিতটি করতে পারেন:

le.fit([y for x in df.get_values() for y in x])

এই ক্ষেত্রে, আপনার সম্ভবত সম্ভবত অ-অনন্য সারি লেবেল রয়েছে (আপনার প্রশ্নে প্রদর্শিত হিসাবে)। এনকোডারটি কি ক্লাস তৈরি করেছে তা দেখতে আপনি কি করতে পারেন le.classes_। আপনি নোট করবেন যে এর মধ্যে একই উপাদান থাকা উচিত set(y for x in df.get_values() for y in x)। আবার কোনও সারি লেবেলকে এনকোডড লেবেল ব্যবহারে রূপান্তর করতে le.transform(...)। উদাহরণ হিসাবে, আপনি যদি df.columnsঅ্যারে এবং প্রথম সারিতে প্রথম কলামের জন্য লেবেলটি পুনরুদ্ধার করতে চান তবে আপনি এটি করতে পারেন :

le.transform([df.get_value(0, df.columns[0])])

আপনার মন্তব্যে আপনার প্রশ্নটি কিছুটা জটিল, তবে এখনও তা সম্পাদন করা যেতে পারে:

le.fit([str(z) for z in set((x[0], y) for x in df.iteritems() for y in x[1])])

উপরের কোডটি নিম্নলিখিতটি করে:

  1. (কলাম, সারি) এর সমস্ত জোড়ার একটি অনন্য সংমিশ্রণ তৈরি করুন
  2. টিপলের স্ট্রিং সংস্করণ হিসাবে প্রতিটি জুটি উপস্থাপন করুন। LabelEncoderক্লাসের নাম হিসাবে টিপলসকে সমর্থন করে না এমন ক্লাসটি কাটিয়ে উঠতে এটি একান্তই কার্যকর ।
  3. নতুন আইটেম ফিট করে LabelEncoder

এখন এই নতুন মডেলটি ব্যবহার করতে এটি কিছুটা জটিল। ধরে নিই আমরা পূর্ববর্তী উদাহরণে (ডিএফ.ক্লমগুলিতে প্রথম কলাম এবং প্রথম সারিতে) একই আইটেমটির জন্য উপস্থাপনাটি বের করতে চাই, আমরা এটি করতে পারি:

le.transform([str((df.columns[0], df.get_value(0, df.columns[0])))])

মনে রাখবেন যে প্রতিটি অনুসন্ধান এখন একটি টিউলের স্ট্রিং উপস্থাপনা যা এতে (কলাম, সারি) রয়েছে।


5

না, LabelEncoderএই না। এটি শ্রেণির লেবেলের 1-ডি অ্যারে নেয় এবং 1-ডি অ্যারে তৈরি করে। এটি শ্রেণিবদ্ধকরণ সমস্যাগুলিতে শ্রেণিবদ্ধ লেবেলগুলি হ্যান্ডেল করার জন্য ডিজাইন করা হয়েছে, স্বেচ্ছাসেবী তথ্য নয় এবং এটিকে অন্য ব্যবহারে জোর করে তোলার যে কোনও প্রয়াসের জন্য সমস্যাটির সমাধান হওয়া প্রকৃত সমস্যাটিকে রূপান্তর করতে (এবং সমাধানটি মূল জায়গাতে ফিরে আসতে হবে) কোডের প্রয়োজন হবে।


ঠিক আছে, এটি দেওয়া, আমি DataFrameএকবারে স্ট্রিং লেবেলগুলিকে পুরোপুরিভাবে এনকোড করতে পারি তার সর্বোত্তম উপায় সম্পর্কে আপনার পরামর্শ কী ?
ব্রায়ান

@ ব্রায়ান কোডটি দেখুন LabelEncoderএবং এটিকে মানিয়ে নিন। আমি নিজে পান্ডা ব্যবহার করি না, তাই আমি জানি না যে কতটা শক্ত হবে।
ফ্রেড ফু

আমি অন্যান্য pandasজনগণকেও এই প্রশ্নটিতে কটাক্ষপাত করতে দেব - আমি নিশ্চিত যে এই চ্যালেঞ্জের সাথে আমিই একমাত্র ব্যক্তি নই, তাই আমি আশা করি সেখানে একটি প্রাক-বিল্ট সমাধান হতে পারে।
ব্রায়ান

5

এটি বাস্তবতার পরে দেড় বছর, তবে আমারও .transform()একবারে একাধিক প্যান্ডাস ডেটাফ্রেম কলামগুলিতে সক্ষম হওয়ার দরকার ছিল (এবং সেগুলিও সক্ষম হয়ে উঠবে .inverse_transform())। এটি উপরের @ প্রাইসহার্ডম্যানের দুর্দান্ত পরামর্শের উপর প্রসারিত:

class MultiColumnLabelEncoder(LabelEncoder):
    """
    Wraps sklearn LabelEncoder functionality for use on multiple columns of a
    pandas dataframe.

    """
    def __init__(self, columns=None):
        self.columns = columns

    def fit(self, dframe):
        """
        Fit label encoder to pandas columns.

        Access individual column classes via indexig `self.all_classes_`

        Access individual column encoders via indexing
        `self.all_encoders_`
        """
        # if columns are provided, iterate through and get `classes_`
        if self.columns is not None:
            # ndarray to hold LabelEncoder().classes_ for each
            # column; should match the shape of specified `columns`
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            self.all_encoders_ = np.ndarray(shape=self.columns.shape,
                                            dtype=object)
            for idx, column in enumerate(self.columns):
                # fit LabelEncoder to get `classes_` for the column
                le = LabelEncoder()
                le.fit(dframe.loc[:, column].values)
                # append the `classes_` to our ndarray container
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                # append this column's encoder
                self.all_encoders_[idx] = le
        else:
            # no columns specified; assume all are to be encoded
            self.columns = dframe.iloc[:, :].columns
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            for idx, column in enumerate(self.columns):
                le = LabelEncoder()
                le.fit(dframe.loc[:, column].values)
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
        return self

    def fit_transform(self, dframe):
        """
        Fit label encoder and return encoded labels.

        Access individual column classes via indexing
        `self.all_classes_`

        Access individual column encoders via indexing
        `self.all_encoders_`

        Access individual column encoded labels via indexing
        `self.all_labels_`
        """
        # if columns are provided, iterate through and get `classes_`
        if self.columns is not None:
            # ndarray to hold LabelEncoder().classes_ for each
            # column; should match the shape of specified `columns`
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            self.all_encoders_ = np.ndarray(shape=self.columns.shape,
                                            dtype=object)
            self.all_labels_ = np.ndarray(shape=self.columns.shape,
                                          dtype=object)
            for idx, column in enumerate(self.columns):
                # instantiate LabelEncoder
                le = LabelEncoder()
                # fit and transform labels in the column
                dframe.loc[:, column] =\
                    le.fit_transform(dframe.loc[:, column].values)
                # append the `classes_` to our ndarray container
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
                self.all_labels_[idx] = le
        else:
            # no columns specified; assume all are to be encoded
            self.columns = dframe.iloc[:, :].columns
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            for idx, column in enumerate(self.columns):
                le = LabelEncoder()
                dframe.loc[:, column] = le.fit_transform(
                        dframe.loc[:, column].values)
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
        return dframe.loc[:, self.columns].values

    def transform(self, dframe):
        """
        Transform labels to normalized encoding.
        """
        if self.columns is not None:
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[
                    idx].transform(dframe.loc[:, column].values)
        else:
            self.columns = dframe.iloc[:, :].columns
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .transform(dframe.loc[:, column].values)
        return dframe.loc[:, self.columns].values

    def inverse_transform(self, dframe):
        """
        Transform labels back to original encoding.
        """
        if self.columns is not None:
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .inverse_transform(dframe.loc[:, column].values)
        else:
            self.columns = dframe.iloc[:, :].columns
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .inverse_transform(dframe.loc[:, column].values)
        return dframe.loc[:, self.columns].values

উদাহরণ:

যদি dfএবং df_copy()মিশ্র- pandasটাইপযুক্ত ডেটাফ্রেম MultiColumnLabelEncoder()হয় তবে আপনি dtype=objectকলামগুলিতে নিম্নলিখিত পদ্ধতিতে প্রয়োগ করতে পারেন :

# get `object` columns
df_object_columns = df.iloc[:, :].select_dtypes(include=['object']).columns
df_copy_object_columns = df_copy.iloc[:, :].select_dtypes(include=['object']).columns

# instantiate `MultiColumnLabelEncoder`
mcle = MultiColumnLabelEncoder(columns=object_columns)

# fit to `df` data
mcle.fit(df)

# transform the `df` data
mcle.transform(df)

# returns output like below
array([[1, 0, 0, ..., 1, 1, 0],
       [0, 5, 1, ..., 1, 1, 2],
       [1, 1, 1, ..., 1, 1, 2],
       ..., 
       [3, 5, 1, ..., 1, 1, 2],

# transform `df_copy` data
mcle.transform(df_copy)

# returns output like below (assuming the respective columns 
# of `df_copy` contain the same unique values as that particular 
# column in `df`
array([[1, 0, 0, ..., 1, 1, 0],
       [0, 5, 1, ..., 1, 1, 2],
       [1, 1, 1, ..., 1, 1, 2],
       ..., 
       [3, 5, 1, ..., 1, 1, 2],

# inverse `df` data
mcle.inverse_transform(df)

# outputs data like below
array([['August', 'Friday', '2013', ..., 'N', 'N', 'CA'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['August', 'Monday', '2014', ..., 'N', 'N', 'NJ'],
       ..., 
       ['February', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['March', 'Tuesday', '2013', ..., 'N', 'N', 'NJ']], dtype=object)

# inverse `df_copy` data
mcle.inverse_transform(df_copy)

# outputs data like below
array([['August', 'Friday', '2013', ..., 'N', 'N', 'CA'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['August', 'Monday', '2014', ..., 'N', 'N', 'NJ'],
       ..., 
       ['February', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['March', 'Tuesday', '2013', ..., 'N', 'N', 'NJ']], dtype=object)

আপনি ইনডেক্সিংয়ের মাধ্যমে প্রতিটি কলামে ফিট করতে ব্যবহৃত পৃথক কলাম শ্রেণি, কলাম লেবেল এবং কলাম এনকোডারগুলি অ্যাক্সেস করতে পারেন:

mcle.all_classes_
mcle.all_encoders_
mcle.all_labels_


হাই জেসন, মাইকেল.এল_বেলস_ কাজ করে না বলে মনে হচ্ছে (পাইথন ৩.৩, কনডা ৪.৩.২৯, স্ক্লেয়ারন ০.০৮.১, পান্ডাস ০.২০.১. আমি পেয়েছি: অ্যাট্রিবিউটআরার: 'মাল্টিক্লম্বলবেল'এনকোডার' অবজেক্টটির কোনও বৈশিষ্ট্য নেই 'all_labels_'
জেসন

@ জেসন হাই, দুঃখিত, আমি আজ অবধি এটি দেখতে পাইনি: / তবে যদি আমার অনুমান করতে হয় তবে আমি বলতে পারি যে আপনি কেবল fitউপরে থেকে এমন পদ্ধতি ব্যবহার করেছেন যা আপনি প্রয়োগ করতে ( transform/ fit_transform) প্রয়োগ না করা পর্যন্ত আসলে কোনও লেবেল তৈরি করে না তথ্যটি.
জেসন ওলোসনোভিচ

আমার মনে হয় আপনার আরও ভাল উদাহরণ স্থাপন করা দরকার - আমি আপনার সমস্ত কোড পুনরায় চালাতে পারিনি।
ব্যবহারকারী 702846

2

@ প্রাইসহার্ডম্যানের সমাধান সম্পর্কে উত্থাপিত মন্তব্যগুলি অনুসরণ করে আমি ক্লাসের নিম্নলিখিত সংস্করণটি প্রস্তাব করব:

class LabelEncodingColoumns(BaseEstimator, TransformerMixin):
def __init__(self, cols=None):
    pdu._is_cols_input_valid(cols)
    self.cols = cols
    self.les = {col: LabelEncoder() for col in cols}
    self._is_fitted = False

def transform(self, df, **transform_params):
    """
    Scaling ``cols`` of ``df`` using the fitting

    Parameters
    ----------
    df : DataFrame
        DataFrame to be preprocessed
    """
    if not self._is_fitted:
        raise NotFittedError("Fitting was not preformed")
    pdu._is_cols_subset_of_df_cols(self.cols, df)

    df = df.copy()

    label_enc_dict = {}
    for col in self.cols:
        label_enc_dict[col] = self.les[col].transform(df[col])

    labelenc_cols = pd.DataFrame(label_enc_dict,
        # The index of the resulting DataFrame should be assigned and
        # equal to the one of the original DataFrame. Otherwise, upon
        # concatenation NaNs will be introduced.
        index=df.index
    )

    for col in self.cols:
        df[col] = labelenc_cols[col]
    return df

def fit(self, df, y=None, **fit_params):
    """
    Fitting the preprocessing

    Parameters
    ----------
    df : DataFrame
        Data to use for fitting.
        In many cases, should be ``X_train``.
    """
    pdu._is_cols_subset_of_df_cols(self.cols, df)
    for col in self.cols:
        self.les[col].fit(df[col])
    self._is_fitted = True
    return self

এই শ্রেণিটি প্রশিক্ষণের সেটটিতে এনকোডারটিকে ফিট করে এবং রূপান্তর করার সময় লাগানো সংস্করণ ব্যবহার করে। কোডটির প্রাথমিক সংস্করণটি এখানে পাওয়া যাবে


2

এর সাথে LabelEncoder()একাধিক কলামে সংক্ষিপ্ত পথ dict():

from sklearn.preprocessing import LabelEncoder
le_dict = {col: LabelEncoder() for col in columns }
for col in columns:
    le_dict[col].fit_transform(df[col])

এবং আপনি এটি le_dictঅন্য যে কোনও কলামে লেবেল এনকোড করতে ব্যবহার করতে পারেন :

le_dict[col].transform(df_another[col])

2

সরাসরি পান্ডসে এটি করা সম্ভব এবং এটির একটি অনন্য দক্ষতার জন্য উপযুক্ত suited replace পদ্ধতির ।

প্রথমে কলামগুলি এবং তাদের মানগুলি তাদের নতুন প্রতিস্থাপনের মানগুলিতে ম্যাপ করার জন্য অভিধানের একটি অভিধান তৈরি করুন।

transform_dict = {}
for col in df.columns:
    cats = pd.Categorical(df[col]).categories
    d = {}
    for i, cat in enumerate(cats):
        d[cat] = i
    transform_dict[col] = d

transform_dict
{'location': {'New_York': 0, 'San_Diego': 1},
 'owner': {'Brick': 0, 'Champ': 1, 'Ron': 2, 'Veronica': 3},
 'pets': {'cat': 0, 'dog': 1, 'monkey': 2}}

যেহেতু এটি সর্বদা এক থেকে এক ম্যাপিং থাকবে তাই আমরা নতুন মানগুলি ম্যাপিংয়ে ফিরে আসার জন্য অভ্যন্তরীণ অভিধানটি উল্টাতে পারি।

inverse_transform_dict = {}
for col, d in transform_dict.items():
    inverse_transform_dict[col] = {v:k for k, v in d.items()}

inverse_transform_dict
{'location': {0: 'New_York', 1: 'San_Diego'},
 'owner': {0: 'Brick', 1: 'Champ', 2: 'Ron', 3: 'Veronica'},
 'pets': {0: 'cat', 1: 'dog', 2: 'monkey'}}

এখন, আমরা replaceঅভিধানের নেস্টেড তালিকা নিতে এবং কলাম হিসাবে বাহ্যিক কীগুলি এবং অভ্যন্তরীণ কীগুলি আমরা প্রতিস্থাপন করতে চাই মান হিসাবে ব্যবহার করতে পদ্ধতির অনন্য ক্ষমতা ব্যবহার করতে পারি।

df.replace(transform_dict)
   location  owner  pets
0         1      1     0
1         0      2     1
2         0      0     0
3         1      1     2
4         1      3     1
5         0      2     1

replaceপদ্ধতিটি পুনরায় শিকল দিয়ে আমরা সহজেই মূলটিতে ফিরে যেতে পারি

df.replace(transform_dict).replace(inverse_transform_dict)
    location     owner    pets
0  San_Diego     Champ     cat
1   New_York       Ron     dog
2   New_York     Brick     cat
3  San_Diego     Champ  monkey
4  San_Diego  Veronica     dog
5   New_York       Ron     dog

2

এখানে এবং অন্য কোথাও কয়েকটি উত্তর নিয়ে প্রচুর অনুসন্ধান এবং পরীক্ষার পরে, আমি মনে করি আপনার উত্তর এখানে রয়েছে :

পিডি.ডাটাফ্রেম (কলামগুলি = ডিএফ.কলোম, ডেটা = লেবেল এনকোডার ()। ফিট_টান্সফর্ম (df.values.flatten ())

এটি কলামগুলিতে বিভাগের নামগুলি সংরক্ষণ করবে:

import pandas as pd
from sklearn.preprocessing import LabelEncoder

df = pd.DataFrame([['A','B','C','D','E','F','G','I','K','H'],
                   ['A','E','H','F','G','I','K','','',''],
                   ['A','C','I','F','H','G','','','','']], 
                  columns=['A1', 'A2', 'A3','A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10'])

pd.DataFrame(columns=df.columns, data=LabelEncoder().fit_transform(df.values.flatten()).reshape(df.shape))

    A1  A2  A3  A4  A5  A6  A7  A8  A9  A10
0   1   2   3   4   5   6   7   9   10  8
1   1   5   8   6   7   9   10  0   0   0
2   1   3   9   6   8   7   0   0   0   0

2

আমি লেবেলএনকোডার এর উত্স কোড ( https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/preprocessing/label.py ) চেক করেছি। এটি নির্লিপ্ত রূপান্তরের একটি সেটের উপর ভিত্তি করে তৈরি হয়েছিল, যার মধ্যে একটি এনপি.উনিক ()। এবং এই ফাংশনটি কেবল 1-ডি অ্যারে ইনপুট নেয়। (আমি ভুল হলে আমাকে সংশোধন করুন)।

খুব রুক্ষ ধারণাগুলি ... প্রথমে কোন কলামগুলিতে লেবেল এনকোডার প্রয়োজন তা শনাক্ত করুন, তারপরে প্রতিটি কলামের মধ্য দিয়ে লুপ করুন।

def cat_var(df): 
    """Identify categorical features. 

    Parameters
    ----------
    df: original df after missing operations 

    Returns
    -------
    cat_var_df: summary df with col index and col name for all categorical vars
    """
    col_type = df.dtypes
    col_names = list(df)

    cat_var_index = [i for i, x in enumerate(col_type) if x=='object']
    cat_var_name = [x for i, x in enumerate(col_names) if i in cat_var_index]

    cat_var_df = pd.DataFrame({'cat_ind': cat_var_index, 
                               'cat_name': cat_var_name})

    return cat_var_df



from sklearn.preprocessing import LabelEncoder 

def column_encoder(df, cat_var_list):
    """Encoding categorical feature in the dataframe

    Parameters
    ----------
    df: input dataframe 
    cat_var_list: categorical feature index and name, from cat_var function

    Return
    ------
    df: new dataframe where categorical features are encoded
    label_list: classes_ attribute for all encoded features 
    """

    label_list = []
    cat_var_df = cat_var(df)
    cat_list = cat_var_df.loc[:, 'cat_name']

    for index, cat_feature in enumerate(cat_list): 

        le = LabelEncoder()

        le.fit(df.loc[:, cat_feature])    
        label_list.append(list(le.classes_))

        df.loc[:, cat_feature] = le.transform(df.loc[:, cat_feature])

    return df, label_list

এনকোডিংয়ের পরে ফিরে আসা ডিএফ হ'ল লেবেল_লিস্ট আপনাকে দেখাবে কি সব সংশ্লিষ্ট কলামে যারা মান উপায়। এটি কাজের জন্য আমি লিখেছি এমন ডেটা প্রক্রিয়া স্ক্রিপ্টের একটি স্নিপেট। আপনি যদি ভাবেন যে আরও কোনও উন্নতি হতে পারে তবে আমাকে জানান।

সম্পাদনা: কেবল এখানে উল্লেখ করতে চাই যে উপরের পদ্ধতিগুলি ডেটা ফ্রেমের সাথে কাজ করে যা সেরা খুঁজে পাওয়া যায় না। এটি কীভাবে ডেটা ফ্রেমের দিকে কাজ করছে তা অনুপস্থিত ডেটা রয়েছে Not (উপরের পদ্ধতিগুলি কার্যকর করার আগে আমার অনুপস্থিত পদ্ধতির সাথে চুক্তি হয়েছিল)


1

লেবেল এনকোডিং করার জন্য যদি আমাদের একক কলাম থাকে এবং অজগরটিতে একাধিক কলাম থাকে তবে এর বিপরীতটি কীভাবে এটি করা যায় তা সহজ রূপান্তরিত করে

def stringtocategory(dataset):
    '''
    @author puja.sharma
    @see The function label encodes the object type columns and gives label      encoded and inverse tranform of the label encoded data
    @param dataset dataframe on whoes column the label encoding has to be done
    @return label encoded and inverse tranform of the label encoded data.
   ''' 
   data_original = dataset[:]
   data_tranformed = dataset[:]
   for y in dataset.columns:
       #check the dtype of the column object type contains strings or chars
       if (dataset[y].dtype == object):
          print("The string type features are  : " + y)
          le = preprocessing.LabelEncoder()
          le.fit(dataset[y].unique())
          #label encoded data
          data_tranformed[y] = le.transform(dataset[y])
          #inverse label transform  data
          data_original[y] = le.inverse_transform(data_tranformed[y])
   return data_tranformed,data_original

1

যদি আপনার ডেটাফ্রেমে সংখ্যাসূচক এবং শ্রেণিবদ্ধ উভয় প্রকারের ডেটা থাকে তবে আপনি ব্যবহার করতে পারেন: এখানে এক্স আমার ডেটাফ্রেমটি পৃথক এবং সংখ্যাগত উভয় ভেরিয়েবলযুক্ত

from sklearn import preprocessing
le = preprocessing.LabelEncoder()

for i in range(0,X.shape[1]):
    if X.dtypes[i]=='object':
        X[X.columns[i]] = le.fit_transform(X[X.columns[i]])

দ্রষ্টব্য: আপনি যদি এগুলিকে আবার রূপান্তর করতে আগ্রহী না হন তবে এই কৌশলটি ভাল।


1

নিউরাক্সেল ব্যবহার করা হচ্ছে

TLDR; আপনি এখানে ব্যবহার করতে পারেন FlattenForEach কেবল মত আপনার df প্রয়োগ রুপান্তর বর্গ মোড়কের: FlattenForEach(LabelEncoder(), then_unflatten=True).fit_transform(df)

এই পদ্ধতির সাহায্যে আপনার লেবেল এনকোডারটি নিয়মিত সাইকিট-লাইন পাইপলাইনের মধ্যে ফিট এবং রূপান্তর করতে সক্ষম হবে । আসুন কেবল আমদানি করা যাক:

from sklearn.preprocessing import LabelEncoder
from neuraxle.steps.column_transformer import ColumnTransformer
from neuraxle.steps.loop import FlattenForEach

কলামগুলির জন্য একই ভাগ করা এনকোডার:

এটি ভাগ করে নেওয়ার জন্য কীভাবে একটি ভাগ করা LabelEncoder সমস্ত ডেটাতে প্রয়োগ করা হবে তা এখানে:

    p = FlattenForEach(LabelEncoder(), then_unflatten=True)

ফলাফল:

    p, predicted_output = p.fit_transform(df.values)
    expected_output = np.array([
        [6, 7, 6, 8, 7, 7],
        [1, 3, 0, 1, 5, 3],
        [4, 2, 2, 4, 4, 2]
    ]).transpose()
    assert np.array_equal(predicted_output, expected_output)

প্রতি কলামে বিভিন্ন এনকোডার:

এবং এখানে কীভাবে পোষা প্রাণীর উপর প্রথম স্বতন্ত্র লেবেল এনকোডার প্রয়োগ করা হবে এবং একটি দ্বিতীয় কলামের মালিক এবং অবস্থানের জন্য ভাগ করা হবে। সুনির্দিষ্টভাবে বলতে গেলে, আমাদের এখানে বিভিন্ন এবং ভাগ করা লেবেল এনকোডারগুলির একটি মিশ্রণ রয়েছে:

    p = ColumnTransformer([
        # A different encoder will be used for column 0 with name "pets":
        (0, FlattenForEach(LabelEncoder(), then_unflatten=True)),
        # A shared encoder will be used for column 1 and 2, "owner" and "location":
        ([1, 2], FlattenForEach(LabelEncoder(), then_unflatten=True)),
    ], n_dimension=2)

ফলাফল:

    p, predicted_output = p.fit_transform(df.values)
    expected_output = np.array([
        [0, 1, 0, 2, 1, 1],
        [1, 3, 0, 1, 5, 3],
        [4, 2, 2, 4, 4, 2]
    ]).transpose()
    assert np.array_equal(predicted_output, expected_output)

0

মূলত @ আলেকজান্ডার উত্তর ব্যবহার করা হয়েছে তবে কিছু পরিবর্তন করতে হয়েছিল -

cols_need_mapped = ['col1', 'col2']

mapper = {col: {cat: n for n, cat in enumerate(df[col].astype('category').cat.categories)} 
     for col in df[cols_need_mapped]}

for c in cols_need_mapped :
    df[c] = df[c].map(mapper[c])

তারপরে ভবিষ্যতে পুনরায় ব্যবহার করতে আপনি কেবল একটি জসন নথিতে আউটপুট সংরক্ষণ করতে পারবেন এবং যখন আপনার এটি প্রয়োজন হবে তখন আপনি এটি পড়তে পারেন এবং .map()আমি উপরে যেমন ফাংশন ব্যবহার করেছি সেগুলি ব্যবহার করতে পারেন।


0

সমস্যাটি হ'ল ডেটা (পিডি ডেটাফ্রেম) এর আকার যা আপনি ফিট ফাংশনে চলে যাচ্ছেন। আপনার 1 ডি তালিকা পাস করতে হবে।


0
import pandas as pd
from sklearn.preprocessing import LabelEncoder

train=pd.read_csv('.../train.csv')

#X=train.loc[:,['waterpoint_type_group','status','waterpoint_type','source_class']].values
# Create a label encoder object 
def MultiLabelEncoder(columnlist,dataframe):
    for i in columnlist:

        labelencoder_X=LabelEncoder()
        dataframe[i]=labelencoder_X.fit_transform(dataframe[i])
columnlist=['waterpoint_type_group','status','waterpoint_type','source_class','source_type']
MultiLabelEncoder(columnlist,train)

এখানে আমি অবস্থান থেকে একটি সিএসভি পড়ছি এবং কার্যক্রমে আমি কলামের তালিকাটি পাস করছি যা আমি লেবেলেনকোড করতে চাই এবং ডেটা ফ্রেমটি আমি এটি প্রয়োগ করতে চাই।


0

এ কেমন?

def MultiColumnLabelEncode(choice, columns, X):
    LabelEncoders = []
    if choice == 'encode':
        for i in enumerate(columns):
            LabelEncoders.append(LabelEncoder())
        i=0    
        for cols in columns:
            X[:, cols] = LabelEncoders[i].fit_transform(X[:, cols])
            i += 1
    elif choice == 'decode': 
        for cols in columns:
            X[:, cols] = LabelEncoders[i].inverse_transform(X[:, cols])
            i += 1
    else:
        print('Please select correct parameter "choice". Available parameters: encode/decode')

এটি সবচেয়ে কার্যকর নয়, তবে এটি কাজ করে এবং এটি অত্যন্ত সাধারণ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.