python - নমপি অ্যারে ফাংশন ম্যাপ করার সর্বাধিক দক্ষ উপায়




performance numpy (6)

টি এল; ডিআর

@user2357112 দ্বারা উল্লিখিত হিসাবে, ফাংশনটি প্রয়োগের একটি "প্রত্যক্ষ" পদ্ধতি নম্পি অ্যারেগুলির উপরে ফাংশনটি মানচিত্রের সর্বদা দ্রুত এবং সহজতম উপায়:

import numpy as np
x = np.array([1, 2, 3, 4, 5])
f = lambda x: x ** 2
squares = f(x)

সাধারণত np.vectorize , কারণ এটি ভাল সঞ্চালন করে না, এবং এর বেশ কয়েকটি issues রয়েছে (বা ছিল)। আপনি যদি অন্য ডেটা প্রকারগুলি পরিচালনা করছেন তবে আপনি নীচে প্রদর্শিত অন্যান্য পদ্ধতিগুলি তদন্ত করতে চাইতে পারেন।

পদ্ধতির তুলনা

ফাংশন ম্যাপ করার জন্য তিনটি পদ্ধতির তুলনা করার জন্য এখানে কয়েকটি সাধারণ পরীক্ষা রয়েছে, উদাহরণস্বরূপ পাইথন ৩.6 এবং নুমপি ১.১15.৪ ব্যবহার করে। প্রথমত, পরীক্ষার জন্য সেট-আপ ফাংশন:

import timeit
import numpy as np

f = lambda x: x ** 2
vf = np.vectorize(f)

def test_array(x, n):
    t = timeit.timeit(
        'np.array([f(xi) for xi in x])',
        'from __main__ import np, x, f', number=n)
    print('array: {0:.3f}'.format(t))

def test_fromiter(x, n):
    t = timeit.timeit(
        'np.fromiter((f(xi) for xi in x), x.dtype, count=len(x))',
        'from __main__ import np, x, f', number=n)
    print('fromiter: {0:.3f}'.format(t))

def test_direct(x, n):
    t = timeit.timeit(
        'f(x)',
        'from __main__ import x, f', number=n)
    print('direct: {0:.3f}'.format(t))

def test_vectorized(x, n):
    t = timeit.timeit(
        'vf(x)',
        'from __main__ import x, vf', number=n)
    print('vectorized: {0:.3f}'.format(t))

পাঁচটি উপাদান দিয়ে পরীক্ষা করা (দ্রুত থেকে ধীরে ধীরে সাজানো):

x = np.array([1, 2, 3, 4, 5])
n = 100000
test_direct(x, n)      # 0.265
test_fromiter(x, n)    # 0.479
test_array(x, n)       # 0.865
test_vectorized(x, n)  # 2.906

100 টি উপাদান সহ:

x = np.arange(100)
n = 10000
test_direct(x, n)      # 0.030
test_array(x, n)       # 0.501
test_vectorized(x, n)  # 0.670
test_fromiter(x, n)    # 0.883

এবং অ্যারের উপাদান বা আরও অনেকের সাথে:

x = np.arange(1000)
n = 1000
test_direct(x, n)      # 0.007
test_fromiter(x, n)    # 0.479
test_array(x, n)       # 0.516
test_vectorized(x, n)  # 0.945

পাইথন / নম্পপি এবং সংকলক অপ্টিমাইজেশনের বিভিন্ন সংস্করণে পৃথক ফলাফল হবে, তাই আপনার পরিবেশের জন্য একই পরীক্ষা করুন।

একটি নমপি অ্যারে উপর ফাংশন মানচিত্র করার সবচেয়ে কার্যকর উপায় কি? আমার বর্তমান প্রকল্পে আমি যেভাবে এটি করছি তা হ'ল:

import numpy as np 

x = np.array([1, 2, 3, 4, 5])

# Obtain array of square of each element in x
squarer = lambda t: t ** 2
squares = np.array([squarer(xi) for xi in x])

তবে এটি সম্ভবত খুব অদক্ষ বলে মনে হচ্ছে, যেহেতু আমি একটি অ্যারি অ্যারেতে রূপান্তর করার আগে পাইথন তালিকা হিসাবে নতুন অ্যারে তৈরি করতে একটি তালিকা বোঝার ব্যবহার করছি।

আমরা কি আরও ভাল করতে পারি?


আমি নম্পির নতুন সংস্করণে (আমি 1.13 ব্যবহার করি) বিশ্বাস করি আপনি স্কেলার প্রকারের জন্য যে লিখনটি লিখেছিলেন তা ফম্পিকে কেবল নিম্পি অ্যারেটি দিয়ে ফাংশনটি কল করতে পারেন, এটি স্বয়ংক্রিয়ভাবে প্রতিটি অ্যালিমিতে ফাংশন কলটি নাম্পার অ্যারের উপরে প্রয়োগ করে আপনাকে ফিরে আসবে আরেকটি নপি অ্যারে

>>> import numpy as np
>>> squarer = lambda t: t ** 2
>>> x = np.array([1, 2, 3, 4, 5])
>>> squarer(x)
array([ 1,  4,  9, 16, 25])


দেখে মনে হচ্ছে কেউ ন্যালি প্যাকেজে ইউফুঙ্ক উত্পাদন করার জন্য বিল্ট-ইন কারখানার পদ্ধতির উল্লেখ করেনি: np.frompyfunc যা আমি আবার পরীক্ষা করেছি np.vectorize এবং প্রায় 20 ~ 30% দ্বারা পেরেছি। অবশ্যই এটি নির্ধারিত সি কোড বা এমনকি numba (যা আমি পরীক্ষা করিনি) হিসাবে ভাল সম্পাদন করবে, তবে এটি np.vectorize চেয়ে ভাল বিকল্প হতে np.vectorize

f = lambda x, y: x * y
f_arr = np.frompyfunc(f, 2, 1)
vf = np.vectorize(f)
arr = np.linspace(0, 1, 10000)

%timeit f_arr(arr, arr) # 307ms
%timeit vf(arr, arr) # 450ms

আমি আরও বড় নমুনাগুলি পরীক্ষা করেছি এবং উন্নতি আনুপাতিক। here ডকুমেন্টেশন দেখুন


হয়তো ভেক্টরাইজ ব্যবহার করা আরও ভাল

def square(x):
   return x**2

vfunc=vectorize(square)

vfunc([1,2,3,4,5])

output:array([ 1,  4,  9, 16, 25])

এই পোস্টে উল্লিখিত হিসাবে, ঠিক যেমন জেনারেটর এক্সপ্রেশন ব্যবহার করুন:

numpy.fromiter((<some_func>(x) for x in <something>),<dtype>,<size of something>)






numpy