NumPy এ অ্যারে কিভাবে স্বাভাবিক করবেন?


202

আমি একটি নম্পপি অ্যারের আদর্শ পেতে চাই। আরও সুনির্দিষ্টভাবে, আমি এই ফাংশনটির সমতুল্য সংস্করণটি খুঁজছি

def normalize(v):
    norm = np.linalg.norm(v)
    if norm == 0: 
       return v
    return v / norm

এর মধ্যেও কি এমন কিছু আছে skearnনাকি numpy?

এই ফাংশনটি এমন পরিস্থিতিতে কাজ করে যেখানে v0 ভেক্টর।


3
আপনি যা লিখেছেন তাতে ভুল কি?
ali_m

5
যদি এটি সত্যিই উদ্বেগজনক হয় তবে আপনার আদর্শ <epsilon পরীক্ষা করা উচিত, যেখানে অ্যাপসিলন একটি ছোট সহনশীলতা। তদ্ব্যতীত, আমি নিঃশব্দে কোনও আদর্শ শূন্য ভেক্টরকে ফেরত দেব না, আমিও raiseব্যতিক্রম!
লাগানো

4
আমার ফাংশনটি কাজ করে তবে অজগরটির আরও সাধারণ লাইব্রেরির ভিতরে কিছু আছে কিনা তা আমি জানতে চাই। আমি বিভিন্ন মেশিন লার্নিং ফাংশন লিখছি এবং কোডটি আরও স্পষ্ট এবং পঠনযোগ্য করার জন্য আমি খুব বেশি নতুন ফাংশন সংজ্ঞায়িত করা এড়াতে চাই
ডোনবিও

1
আমি কয়েকটি দ্রুত পরীক্ষা করেছি এবং আমি দেখতে পেলাম যে একটি সিপিইউতে আকাঙ্ক্ষিত 1.15.1 এর x/np.linalg.norm(x)চেয়ে খুব ধীর (প্রায় 15-20%) ছিল x/np.sqrt((x**2).sum())না।
বিল

উত্তর:


160

আপনি যদি বিজ্ঞান-ব্যবহার শিখছেন তবে আপনি এটি ব্যবহার করতে পারেন sklearn.preprocessing.normalize:

import numpy as np
from sklearn.preprocessing import normalize

x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = normalize(x[:,np.newaxis], axis=0).ravel()
print np.all(norm1 == norm2)
# True

2
উত্তরের জন্য ধন্যবাদ তবে আপনি কি নিশ্চিত যে sklearn.preprocessing.normalize আকৃতির ভেক্টর = (এন,) বা (এন, 1) এর সাথেও কাজ করে? এই লাইব্রেরিতে আমার কিছু সমস্যা হচ্ছে
ডোনবিও

normalizeএকটি 2 ডি ইনপুট প্রয়োজন। আপনি axis=নিজের ইনপুট অ্যারের সারি বা কলামগুলি জুড়ে সাধারণীকরণ প্রয়োগ করতে চান কিনা তা নির্দিষ্ট করতে আপনি যুক্তিটি পাস করতে পারেন।
ali_m

9
নোট করুন যে নরমালাইজ ফাংশনের 'আদর্শ' আর্গুমেন্টটি 'l1' বা 'l2' হতে পারে এবং ডিফল্টটি 'l2' হয়। আপনি যদি চান তবে আপনার ভেক্টরের যোগফল 1 হবে (যেমন একটি সম্ভাব্য বিতরণ) আপনার স্বাভাবিককরণের ক্রিয়ায় আদর্শ = 'l1' ব্যবহার করা উচিত।
অ্যাশ

2
এছাড়াও লক্ষ করুন যে np.linalg.norm(x)ডিফল্টরূপে 'l2' আদর্শ গণনা করে। আপনি যদি চান তবে আপনার ভেক্টরের যোগফল 1 হবে আপনার ব্যবহার করা উচিতnp.linalg.norm(x, ord=1)
ওমিড

দ্রষ্টব্য: ফাংশনটির ndarrayসাথে এটি কাজ করার জন্য এক্স হতে হবে normalize()। অন্যথায় এটি হতে পারে একটি list
রামিন মেলিকভ

46

আমি সম্মত হব যে এই জাতীয় ফাংশন অন্তর্ভুক্ত ব্যাটারির অংশ হলে এটি দুর্দান্ত ছিল। তবে এটি আমি জানি না। এখানে স্বেচ্ছাসূচক অক্ষগুলির জন্য একটি সংস্করণ এবং সর্বোত্তম কর্মক্ষমতা দেওয়া।

import numpy as np

def normalized(a, axis=-1, order=2):
    l2 = np.atleast_1d(np.linalg.norm(a, order, axis))
    l2[l2==0] = 1
    return a / np.expand_dims(l2, axis)

A = np.random.randn(3,3,3)
print(normalized(A,0))
print(normalized(A,1))
print(normalized(A,2))

print(normalized(np.arange(3)[:,None]))
print(normalized(np.arange(3)))

আমি গভীরভাবে আলি_মি সমাধানটি পরীক্ষা করিনি তবে কিছু সাধারণ ক্ষেত্রে এটি কাজ করছে বলে মনে হচ্ছে। আপনার ফাংশনটি আরও ভাল করে এমন পরিস্থিতি রয়েছে?
ডনবিও

1
আমি জানি না; তবে এটি নির্বিচারে অক্ষগুলির উপরে কাজ করে এবং দৈর্ঘ্যের 0 ভেক্টরগুলির জন্য কী ঘটে তার উপর আমাদের স্পষ্ট নিয়ন্ত্রণ রয়েছে।
ইলকো হুগেনডোর্ন

1
খুব সুন্দর! এটি অদ্ভুত হওয়া উচিত - যদিও আমার মতে সম্ভবত অক্ষর আগে অর্ডার আসা উচিত।
নীল জি

অর্ডার = 2 অন্যের চেয়ে কেন বেছে নেওয়া হয়েছে তা বুঝতে ইলকোহিজেন্ডোর্ন কৌতূহল?
হেনরি থর্নটন

7
কারণ ইউক্যালিডিয়ান / পাইথাগোরান আদর্শটি সবচেয়ে বেশি ব্যবহৃত হয়; আপনি কি রাজি হবেন না?
ইলকো হুগেনডোর্ন

21

আপনি এল 1 আদর্শ পেতে অর্ডার নির্দিষ্ট করতে পারেন। শূন্য বিভাগ এড়ানোর জন্য আমি ইপ্স ব্যবহার করি তবে এটি সম্ভবত দুর্দান্ত নয়।

def normalize(v):
    norm=np.linalg.norm(v, ord=1)
    if norm==0:
        norm=np.finfo(v.dtype).eps
    return v/norm

6
[inf, 1, 2]ফলন স্বাভাবিক করা [nan, 0, 0], তবে তা হওয়া উচিত নয় [1, 0, 0]?
পাসবি

12

এটি আপনার পক্ষেও কাজ করতে পারে

import numpy as np
normalized_v = v / np.sqrt(np.sum(v**2))

vদৈর্ঘ্য 0 থাকলে ব্যর্থ হয় ।


10

আপনার যদি বহুমাত্রিক ডেটা থাকে এবং প্রতিটি অক্ষকে তার সর্বোচ্চ বা এর যোগফলকে স্বাভাবিক করতে চান:

def normalize(_d, to_sum=True, copy=True):
    # d is a (n x dimension) np array
    d = _d if not copy else np.copy(_d)
    d -= np.min(d, axis=0)
    d /= (np.sum(d, axis=0) if to_sum else np.ptp(d, axis=0))
    return d

পিক ফাংশন থেকে নিমপিস শিখর ব্যবহার করে।

a = np.random.random((5, 3))

b = normalize(a, copy=False)
b.sum(axis=0) # array([1., 1., 1.]), the rows sum to 1

c = normalize(a, to_sum=False, copy=False)
c.max(axis=0) # array([1., 1., 1.]), the max of each row is 1

আসল ম্যাট্রিক্সে যদি সমস্ত মান একই হয় তবে দেখুন পিটিপি 0 হবে 0 ভাগ করে ন্যান ফিরে আসবে।
মিলসো

8

এছাড়া ফাংশন unit_vector()জনপ্রিয় মধ্যে স্বাভাবিক ভেক্টর থেকে রূপান্তরের ক্রিস্টোফ Gohlke দ্বারা মডিউল:

import transformations as trafo
import numpy as np

data = np.array([[1.0, 1.0, 0.0],
                 [1.0, 1.0, 1.0],
                 [1.0, 2.0, 3.0]])

print(trafo.unit_vector(data, axis=1))

7

আপনি বিজ্ঞান-কিট শিখার উল্লেখ করেছেন, তাই আমি আরও একটি সমাধান ভাগ করতে চাই।

সাই-কিট শিখুন MinMaxScaler

সায়-কিট শিখতে, এমন একটি এপিআই রয়েছে MinMaxScalerযা আপনার পছন্দ অনুসারে মানের সীমাটি কাস্টমাইজ করতে পারে।

এটি আমাদের জন্য এনএএন সংক্রান্ত সমস্যাগুলিও ডিল করে।

এনএএনগুলি অনুপস্থিত মান হিসাবে বিবেচনা করা হয়: উপযুক্তভাবে উপেক্ষা করা, এবং রূপান্তরটিতে রক্ষণাবেক্ষণ করা। ... রেফারেন্স দেখুন [1]

কোড নমুনা

কোডটি সহজ, কেবল টাইপ করুন

# Let's say X_train is your input dataframe
from sklearn.preprocessing import MinMaxScaler
# call MinMaxScaler object
min_max_scaler = MinMaxScaler()
# feed in a numpy array
X_train_norm = min_max_scaler.fit_transform(X_train.values)
# wrap it up if you need a dataframe
df = pd.DataFrame(X_train_norm)
উল্লেখ

6

ছাড়া sklearnএবং ব্যবহার না করে numpy। শুধু একটি ফাংশন সংজ্ঞায়িত:।

ধরে নিচ্ছি যে সারিগুলি ভেরিয়েবল এবং কলামগুলি নমুনাগুলি ( axis= 1):

import numpy as np

# Example array
X = np.array([[1,2,3],[4,5,6]])

def stdmtx(X):
    means = X.mean(axis =1)
    stds = X.std(axis= 1, ddof=1)
    X= X - means[:, np.newaxis]
    X= X / stds[:, np.newaxis]
    return np.nan_to_num(X)

আউটপুট:

X
array([[1, 2, 3],
       [4, 5, 6]])

stdmtx(X)
array([[-1.,  0.,  1.],
       [-1.,  0.,  1.]])

4

আপনি যদি কোনও 3D টেন্সরে সঞ্চিত n মাত্রিক বৈশিষ্ট্যযুক্ত ভেক্টরগুলিকে সাধারণ করতে চান তবে আপনি পাইটর্চও ব্যবহার করতে পারেন:

import numpy as np
from torch import FloatTensor
from torch.nn.functional import normalize

vecs = np.random.rand(3, 16, 16, 16)
norm_vecs = normalize(FloatTensor(vecs), dim=0, eps=1e-16).numpy()

4

যদি আপনার 3D ভেক্টর সঙ্গে কাজ করছেন, তাহলে আপনি সংক্ষেপে toolbelt ব্যবহার করে এই কাজ করতে পারেন VG । এটি নমপির উপরে একটি হালকা স্তর এবং এটি একক মান এবং স্ট্যাকড ভেক্টরগুলিকে সমর্থন করে।

import numpy as np
import vg

x = np.random.rand(1000)*10
norm1 = x / np.linalg.norm(x)
norm2 = vg.normalize(x)
print np.all(norm1 == norm2)
# True

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



3

আপনি যদি বহুমাত্রিক অ্যারে দিয়ে কাজ করেন তবে দ্রুত সমাধানটি সম্ভব।

বলুন আমাদের কাছে 2D অ্যারে রয়েছে, যা আমরা শেষ অক্ষ দ্বারা স্বাভাবিক করতে চাই, কিছু সারিতে শূন্য রীতি রয়েছে।

import numpy as np
arr = np.array([
    [1, 2, 3], 
    [0, 0, 0],
    [5, 6, 7]
], dtype=np.float)

lengths = np.linalg.norm(arr, axis=-1)
print(lengths)  # [ 3.74165739  0.         10.48808848]
arr[lengths > 0] = arr[lengths > 0] / lengths[lengths > 0][:, np.newaxis]
print(arr)
# [[0.26726124 0.53452248 0.80178373]
# [0.         0.         0.        ]
# [0.47673129 0.57207755 0.66742381]]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.