সূচকের অ্যারেটিকে 1-হট এনকোডড নম্পি অ্যারে রূপান্তর করুন


227

ধরা যাক আমার কাছে 1 ডি নাম্পার অ্যারে রয়েছে

a = array([1,0,3])

আমি এটি 2 ডি 1-হট অ্যারে হিসাবে এনকোড করতে চাই

b = array([[0,1,0,0], [1,0,0,0], [0,0,0,1]])

এটি করার কোনও দ্রুত উপায় আছে? এর aউপাদানগুলি সেট করতে কেবল লুপিংয়ের চেয়ে দ্রুত b

উত্তর:


395

আপনার অ্যারে aআউটপুট অ্যারেতে নানজারো উপাদানগুলির কলামগুলি সংজ্ঞায়িত করে। আপনাকে সারিগুলিও সংজ্ঞায়িত করতে হবে এবং তারপরে অভিনব সূচি ব্যবহার করতে হবে:

>>> a = np.array([1, 0, 3])
>>> b = np.zeros((a.size, a.max()+1))
>>> b[np.arange(a.size),a] = 1
>>> b
array([[ 0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.]])

111
সুন্দর। এটিকে কিছুটা সাধারণকরণ করুন b = np.zeros((a.size, a.max()+1)):, তারপরে `বি [এনপি.আরঙ্গ (a.size), a] = 1`
জেমস

10
@ জামেস অ্যাটউড এটি প্রয়োগের উপর নির্ভর করে তবে আমি সর্বোচ্চটি একটি পরামিতি তৈরি করতাম এবং এটি ডেটা থেকে গণনা করি না।
মোহাম্মদ মোগিমি

1
@ মোহাম্মদমোঘিমি শিওর, আমার কাছে তা উপলব্ধি করে।
জেমস অ্যাটউড

7
যদি 'এ' 2 ডি হয়? এবং আপনি একটি 3-ডি এক হট ম্যাট্রিক্স চান?
এড

8
এটি কেন কাজ করে তার ব্যাখ্যাতে কেউ কি ইঙ্গিত করতে পারে তবে [:, a] দিয়ে টুকরোটি করে না?
এন। ম্যাকা

168
>>> values = [1, 0, 3]
>>> n_values = np.max(values) + 1
>>> np.eye(n_values)[values]
array([[ 0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.]])

9
এই দ্রবণটি ইনপুট এনডি ম্যাট্রিক্স থেকে এক হট এন + 1 ডি ম্যাট্রিক্সের জন্য একমাত্র কার্যকর। উদাহরণ: ইনপুট_ম্যাট্রিক্স = এনপি.আসারে ([[0,1,1], [1,1,2]]); np.eye (3) [input_matrix] # আউটপুট 3D টেন্সর
যিশাইয়

5
+1 কারণ এটি গৃহীত সমাধানের চেয়ে বেশি পছন্দ করা উচিত। আরও সাধারণ সমাধানের জন্য যদিও valuesপাইথন তালিকার চেয়ে নম্পি অ্যারে হওয়া উচিত, তবে এটি কেবল 1 ডি-তে নয়, সমস্ত মাত্রায় কাজ করে।
অ্যালেক্স

8
মনে রাখবেন যে np.max(values) + 1আপনার ডেটা সেটটি এলোমেলোভাবে নমুনা হিসাবে বলা হয় এবং সুযোগের মধ্যে এটিতে সর্বোচ্চ মান নাও থাকতে পারে বলে বালতি সংখ্যক হিসাবে নেওয়া পছন্দসই নয়। বালতির সংখ্যার পরিবর্তে একটি প্যারামিটার হওয়া উচিত এবং প্রতিটি মান 0 (Incl) এবং বালতি গণনা (এক্সেল) এর মধ্যে রয়েছে তা পরীক্ষা করার জন্য দৃ /়তা / চেক থাকা উচিত।
নাইটএলফিক

2
আমার কাছে এই সমাধানটি সর্বোত্তম এবং যে কোনও টেনসারে সহজেই সাধারণীকরণ করা যায়: ডিফ ওয়ান_হোট (এক্স, গভীরতা = 10): রিটার্ন এনপি.ইয়ে (গভীরতা) [এক্স]। নোট করুন যে টেনসর এক্সকে সূচক হিসাবে দেওয়ার ফলে x. shape চোখের সারিগুলির একটি সেন্সর ফিরে আসে।
সেকোনুরালে

4
সহজ উপায় এই সমাধান "বুঝতে" থেকে এবং কেন এটা এন-dims জন্য (পড়া ছাড়া কাজ করে numpyদস্তাবেজ): মূল ম্যাট্রিক্স (প্রতিটি অবস্থানে values), আমরা একটি পূর্ণসংখ্যা আছে k, এবং আমরা 1-গরম ভেক্টর "করা" eye(n)[k]যে অবস্থানে । এটি একটি মাত্রা যুক্ত করে কারণ আমরা মূল ম্যাট্রিক্সে একটি ভাস্করের অবস্থানটিতে একটি ভেক্টরকে "স্থাপন" করি।
এভিভার


32

আমি দরকারী মনে করি এটি এখানে:

def one_hot(a, num_classes):
  return np.squeeze(np.eye(num_classes)[a.reshape(-1)])

এখানে num_classesআপনার কাছে ক্লাস সংখ্যা রয়েছে। সুতরাং আপনার যদি (10000,)a আকৃতির ভেক্টর থাকে তবে এই ফাংশনটি এটিকে (10000, সি) রূপান্তর করে । নোট যে শূন্য সূচকযুক্ত, অর্থাত্ দেবে ।aone_hot(np.array([0, 1]), 2)[[1, 0], [0, 1]]

আপনি যা করতে চেয়েছিলেন ঠিক তেমনই আমি বিশ্বাস করি।

পিএস: উত্স হ'ল সিকোয়েন্স মডেল - ডিপলাইনিং.ইই


এছাড়াও, এনপি.স্কুয়েজ () করার জন্য যেহেতু (ভেক্টর এ এর ​​আকার) অনেকগুলি হট এনকোডেড অ্যারে রয়েছে np.eye(num_classes)[a.reshape(-1)]. What you are simply doing is using এনপি.ইইইইউ ব্যবহার করে আপনি প্রতিটি বর্গ সূচকে 1 বাকী শূন্য হিসাবে এবং পরে প্রদত্ত সূচকগুলি ব্যবহার করে তৈরি করছেন দ্বারা a.reshape(-1)উত্পাদক আউটপুটে সূচক সংশ্লিষ্ট np.eye()। আমি প্রয়োজনীয়তা বুঝতে পারি নি np.sqeezeযেহেতু আমরা কেবলমাত্র একক মাত্রা অপসারণ করতে এটি ব্যবহার করি যা আউটপুটটির মাত্রা হিসাবে আমরা কখনই পাই না(a_flattened_size, num_classes)
আনু

27

আপনি ব্যবহার করতে পারেন sklearn.preprocessing.LabelBinarizer:

উদাহরণ:

import sklearn.preprocessing
a = [1,0,3]
label_binarizer = sklearn.preprocessing.LabelBinarizer()
label_binarizer.fit(range(max(a)+1))
b = label_binarizer.transform(a)
print('{0}'.format(b))

আউটপুট:

[[0 1 0 0]
 [1 0 0 0]
 [0 0 0 1]]

অন্যান্য জিনিসের মধ্যে, আপনি সূচনা করতে পারেন sklearn.preprocessing.LabelBinarizer()যাতে আউটপুট transformবিচ্ছিন্ন হয়।


21

আপনি নমপির চোখের কাজটিও ব্যবহার করতে পারেন :

numpy.eye(number of classes)[vector containing the labels]


1
আরও স্পষ্টতার জন্য আরও np.identity(num_classes)[indices]ভাল হতে পারে। চমৎকার উত্তর!
অলিভার

5

এখানে একটি ফাংশন যা 1-ডি ভেক্টরকে 2-ডি ওয়ান-হট অ্যারে রূপান্তর করে।

#!/usr/bin/env python
import numpy as np

def convertToOneHot(vector, num_classes=None):
    """
    Converts an input 1-D vector of integers into an output
    2-D array of one-hot vectors, where an i'th input value
    of j will set a '1' in the i'th row, j'th column of the
    output array.

    Example:
        v = np.array((1, 0, 4))
        one_hot_v = convertToOneHot(v)
        print one_hot_v

        [[0 1 0 0 0]
         [1 0 0 0 0]
         [0 0 0 0 1]]
    """

    assert isinstance(vector, np.ndarray)
    assert len(vector) > 0

    if num_classes is None:
        num_classes = np.max(vector)+1
    else:
        assert num_classes > 0
        assert num_classes >= np.max(vector)

    result = np.zeros(shape=(len(vector), num_classes))
    result[np.arange(len(vector)), vector] = 1
    return result.astype(int)

নীচে কয়েকটি ব্যবহারের উদাহরণ দেওয়া হল:

>>> a = np.array([1, 0, 3])

>>> convertToOneHot(a)
array([[0, 1, 0, 0],
       [1, 0, 0, 0],
       [0, 0, 0, 1]])

>>> convertToOneHot(a, num_classes=10)
array([[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]])

মনে রাখবেন এটি কেবল ভেক্টরগুলিতে কাজ করে (এবং assertভেক্টরের আকৃতি চেক করার কোনও ব্যবস্থা নেই ;))।
jhndodo

1
সাধারণীকরণের পদ্ধতি এবং পরামিতিগুলির পরীক্ষার জন্য +1। তবে, একটি সাধারণ অনুশীলন হিসাবে, আমি ইনপুটগুলিতে চেক সম্পাদন করার জন্য অ্যাসেটগুলি ব্যবহার না করার পরামর্শ দিই। কেবল অভ্যন্তরীণ মধ্যবর্তী অবস্থাগুলি যাচাই করতে অ্যাসেসর্ট ব্যবহার করুন। বরং, সব রূপান্তর assert ___মধ্যে if not ___ raise Exception(<Reason>)
fnunnari

3

1-হট-এনকোডিংয়ের জন্য

   one_hot_encode=pandas.get_dummies(array)

উদাহরণ স্বরূপ

এনজিও কোডিং


মন্তব্যের জন্য ধন্যবাদ, তবে কোড কী করছে তার একটি সংক্ষিপ্ত বিবরণ খুব সহায়ক হবে!
ক্যারোলাস

দয়া করে উদাহরণটি উল্লেখ করুন
শুভম মিশ্র

নিচের উদাহরণটি দেখুন আপনি আপনার এনপি অ্যারেতে প্রতিটি মানের একটি হট এনকোডিং অ্যাক্সেস করতে পারেন_আপনি_কেন্দ্র [মান] করে। >>> import numpy as np >>> import pandas >>> a = np.array([1,0,3]) >>> one_hot_encode=pandas.get_dummies(a) >>> print(one_hot_encode) 0 1 3 0 0 1 0 1 1 0 0 2 0 0 1 >>> print(one_hot_encode[1]) 0 1 1 0 2 0 Name: 1, dtype: uint8 >>> print(one_hot_encode[0]) 0 0 1 1 2 0 Name: 0, dtype: uint8 >>> print(one_hot_encode[3]) 0 0 1 0 2 1 Name: 3, dtype: uint8
দীপক

2

আমি মনে করি সংক্ষিপ্ত উত্তরটি হ'ল না। nমাত্রায় আরও জেনেরিক ক্ষেত্রে , আমি এটি নিয়ে এসেছি:

# For 2-dimensional data, 4 values
a = np.array([[0, 1, 2], [3, 2, 1]])
z = np.zeros(list(a.shape) + [4])
z[list(np.indices(z.shape[:-1])) + [a]] = 1

আমি আরও ভাবছি যে এর থেকে আরও ভাল সমাধান আছে কিনা - আমি পছন্দ করি না যে আমাকে শেষ দুটি লাইনে সেই তালিকা তৈরি করতে হবে। যাইহোক, আমি এর সাথে কিছু পরিমাপ করেছি timeitএবং দেখে মনে হচ্ছে যে numpyবেসড ( indices/ arange) এবং পুনরাবৃত্ত সংস্করণগুলি প্রায় একই কাজ করে।


2

শুধু সম্প্রসারিত করার চমৎকার উত্তর থেকে K3 --- RNC , এখানে আরো একটি জেনেরিক সংস্করণ:

def onehottify(x, n=None, dtype=float):
    """1-hot encode x with the max value n (computed from data if n is None)."""
    x = np.asarray(x)
    n = np.max(x) + 1 if n is None else n
    return np.eye(n, dtype=dtype)[x]

এছাড়াও, এই পদ্ধতির একটি দ্রুত এবং নোংরা মানদণ্ড এবং ওয়াইএক্সডি দ্বারা বর্তমানে গৃহীত উত্তর থেকে একটি পদ্ধতি (কিছুটা পরিবর্তিত হয়েছে, যাতে তারা একই এপিআই সরবরাহ করে যে পরবর্তীতে কেবলমাত্র 1 ডি নাদারের সাথে কাজ করে):

def onehottify_only_1d(x, n=None, dtype=float):
    x = np.asarray(x)
    n = np.max(x) + 1 if n is None else n
    b = np.zeros((len(x), n), dtype=dtype)
    b[np.arange(len(x)), x] = 1
    return b

পরবর্তী পদ্ধতিটি ~ 35% দ্রুত (ম্যাকবুক প্রো 13 2015), তবে পূর্বেরটি আরও সাধারণ:

>>> import numpy as np
>>> np.random.seed(42)
>>> a = np.random.randint(0, 9, size=(10_000,))
>>> a
array([6, 3, 7, ..., 5, 8, 6])
>>> %timeit onehottify(a, 10)
188 µs ± 5.03 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit onehottify_only_1d(a, 10)
139 µs ± 2.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

2

এক-গরম ভেক্টরে রূপান্তর করার জন্য আপনি নীচের কোডটি ব্যবহার করতে পারেন:

x হল সাধারণ শ্রেণীর ভেক্টর যার ক্লাস 0 থেকে কিছু সংখ্যার একক কলাম থাকে:

import numpy as np
np.eye(x.max()+1)[x]

যদি 0 শ্রেণি না হয়; তারপরে +1 সরান।


1

আমি সম্প্রতি একই ধরণের সমস্যার মধ্যে দৌড়েছি এবং বলেছিলাম যে সমাধানটি কেবল সন্তোষজনক বলে প্রমাণিত হয়েছে যদি আপনার নির্দিষ্ট সংস্থার মধ্যে সংখ্যা থাকে তবে। উদাহরণস্বরূপ, যদি আপনি নীচের তালিকার এক-গরম এনকোড করতে চান:

all_good_list = [0,1,2,3,4]

এগিয়ে যান, পোস্ট সমাধান ইতিমধ্যে উপরে উল্লিখিত আছে। তবে এই ডেটা বিবেচনা করলে কী হবে:

problematic_list = [0,23,12,89,10]

আপনি যদি উপরে বর্ণিত পদ্ধতিগুলি সহ এটি করেন তবে আপনি সম্ভবত 90 টি এক-হট কলাম দিয়ে শেষ করবেন। এটি কারণ সমস্ত উত্তরের মতো কিছু থাকে n = np.max(a)+1। আমি একটি আরও জেনেরিক সমাধান পেয়েছি যা আমার জন্য কার্যকর হয়েছিল এবং আপনার সাথে ভাগ করে নিতে চেয়েছিল:

import numpy as np
import sklearn
sklb = sklearn.preprocessing.LabelBinarizer()
a = np.asarray([1,2,44,3,2])
n = np.unique(a)
sklb.fit(n)
b = sklb.transform(a)

আমি আশা করি উপরের সমাধানগুলিতে কেউ একই বিধিনিষেধের সম্মুখীন হয়েছে এবং এটি কার্যকর হতে পারে


1

এ জাতীয় এনকোডিং সাধারণত নমপি অ্যারের অংশ। আপনি যদি এইরকম একটি নমপি অ্যারে ব্যবহার করেন:

a = np.array([1,0,3])

তবে এটিকে 1-হট এনকোডিংয়ে রূপান্তর করার খুব সহজ উপায় রয়েছে

out = (np.arange(4) == a[:,None]).astype(np.float32)

এটাই.


1
  • পি 2 ডি নাদারের হবে।
  • আমরা জানতে চাই যে কোন মানটি সারিতে সর্বোচ্চ, সেখানে 1 এবং অন্য কোথাও 0 রাখুন put

পরিষ্কার এবং সহজ সমাধান:

max_elements_i = np.expand_dims(np.argmax(p, axis=1), axis=1)
one_hot = np.zeros(p.shape)
np.put_along_axis(one_hot, max_elements_i, 1, axis=1)

1

নিউরাক্সেল পাইপলাইন পদক্ষেপ ব্যবহার :

  1. আপনার উদাহরণ স্থাপন করুন
import numpy as np
a = np.array([1,0,3])
b = np.array([[0,1,0,0], [1,0,0,0], [0,0,0,1]])
  1. প্রকৃত রূপান্তর করুন
from neuraxle.steps.numpy import OneHotEncoder
encoder = OneHotEncoder(nb_columns=4)
b_pred = encoder.transform(a)
  1. দৃ works়ভাবে এটি কাজ করে
assert b_pred == b

ডকুমেন্টেশনের লিঙ্ক: neuraxle.steps.numpy.OneHotEncoder


0

এখানে একটি উদাহরণ ফাংশন যা আমি উপরের উত্তর এবং আমার নিজের ব্যবহারের ক্ষেত্রে ভিত্তিতে এটি করতে লিখেছিলাম:

def label_vector_to_one_hot_vector(vector, one_hot_size=10):
    """
    Use to convert a column vector to a 'one-hot' matrix

    Example:
        vector: [[2], [0], [1]]
        one_hot_size: 3
        returns:
            [[ 0.,  0.,  1.],
             [ 1.,  0.,  0.],
             [ 0.,  1.,  0.]]

    Parameters:
        vector (np.array): of size (n, 1) to be converted
        one_hot_size (int) optional: size of 'one-hot' row vector

    Returns:
        np.array size (vector.size, one_hot_size): converted to a 'one-hot' matrix
    """
    squeezed_vector = np.squeeze(vector, axis=-1)

    one_hot = np.zeros((squeezed_vector.size, one_hot_size))

    one_hot[np.arange(squeezed_vector.size), squeezed_vector] = 1

    return one_hot

label_vector_to_one_hot_vector(vector=[[2], [0], [1]], one_hot_size=3)

0

আমি একটি সাধারণ ফাংশন সম্পূর্ণ করার জন্য যুক্ত করছি, কেবল নমপি অপারেটরগুলি ব্যবহার করে:

   def probs_to_onehot(output_probabilities):
        argmax_indices_array = np.argmax(output_probabilities, axis=1)
        onehot_output_array = np.eye(np.unique(argmax_indices_array).shape[0])[argmax_indices_array.reshape(-1)]
        return onehot_output_array

এটি ইনপুট হিসাবে একটি সম্ভাব্যতা ম্যাট্রিক্স হিসাবে লাগে: যেমন:

[[0.03038822 0.65810204 0.16549407 0.3797123] ... [0.02771272 0.2760752 0.3280924 0.33458805]]

এবং এটি ফিরে আসবে

[[0 1 0 0] ... [0 0 0 1]]


0

এখানে একটি মাত্রিকতা-স্বতন্ত্র একক সমাধান।

এটি arrnonnegative পূর্ণসংখ্যার যে কোনও N- মাত্রিক অ্যারেটিকে এক-হট এন + 1-মাত্রিক অ্যারেতে রূপান্তরিত করবে one_hot, one_hot[i_1,...,i_N,c] = 1যার অর্থ arr[i_1,...,i_N] = c। এর মাধ্যমে আপনি ইনপুটটি পুনরুদ্ধার করতে পারেনnp.argmax(one_hot, -1)

def expand_integer_grid(arr, n_classes):
    """

    :param arr: N dim array of size i_1, ..., i_N
    :param n_classes: C
    :returns: one-hot N+1 dim array of size i_1, ..., i_N, C
    :rtype: ndarray

    """
    one_hot = np.zeros(arr.shape + (n_classes,))
    axes_ranges = [range(arr.shape[i]) for i in range(arr.ndim)]
    flat_grids = [_.ravel() for _ in np.meshgrid(*axes_ranges, indexing='ij')]
    one_hot[flat_grids + [arr.ravel()]] = 1
    assert((one_hot.sum(-1) == 1).all())
    assert(np.allclose(np.argmax(one_hot, -1), arr))
    return one_hot

0

নিম্নলিখিত কোড ব্যবহার করুন। এটি সবচেয়ে ভাল কাজ করে।

def one_hot_encode(x):
"""
    argument
        - x: a list of labels
    return
        - one hot encoding matrix (number of labels, number of class)
"""
encoded = np.zeros((len(x), 10))

for idx, val in enumerate(x):
    encoded[idx][val] = 1

return encoded

এটি এখানে পেয়েছে পিএস আপনার লিঙ্কে যাওয়ার দরকার নেই।


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