একটি নমপি অ্যারে বিপরীত করার সবচেয়ে কার্যকরী উপায়


276

বিশ্বাস করুন বা না রাখুন, আমার বর্তমান কোডটি প্রোফাইল করার পরে, নপি অ্যারে পুনর্বিবেচনার পুনরাবৃত্ত ক্রিয়াকলাপটি চলমান সময়ের এক বিশাল অংশটি খেয়েছে। আমার কাছে এখন যা আছে তা সাধারণ ভিউ-ভিত্তিক পদ্ধতি:

reversed_arr = arr[::-1]

এটি আরও দক্ষতার সাথে করার জন্য অন্য কোনও উপায় আছে, বা এটি অবাস্তব নকল কর্মক্ষমতা নিয়ে আমার আবেশ থেকে কেবল একটি মায়া?


27
এর ... arr[::-1]সবেমাত্র একটি বিপরীত দৃশ্য প্রদর্শন করে। এটি যত দ্রুত পাবে তত দ্রুত এবং অ্যারের আইটেমের সংখ্যার উপর নির্ভর করে না, কারণ এটি কেবল ধাপে পরিবর্তন করে। আপনি কি আসলে একটি অদ্ভুত অ্যারে বিপরীত করছেন?
জো কিংটন

হ্যাঁ, প্রকৃতপক্ষে arrএকটি অদ্ভুত অ্যারে is
nye17

12
হুমমম ... ঠিক আছে, আমার ল্যাপটপে এটি অ্যারের দৈর্ঘ্য নির্বিশেষে প্রায় 670 ন্যানোসেকেন্ড নেয়। যদি এটি আপনার বাধা হয়ে থাকে তবে আপনার ভাষাগুলি স্যুইচ করার প্রয়োজন হতে পারে ... আমি দৃ sure়ভাবে নিশ্চিত যে আপনি কোনও ন্যারি অ্যারে পরিবর্তনের দ্রুততর উপায় খুঁজে পাবেন না। শুভকামনা, যে কোনও হারে!
জো কিংটন

6
ঠিক আছে, আপনার কি অগত্যা এটিকে একটি লুপের মধ্যে চালাতে হবে? কিছু ক্ষেত্রে, কয়েক মিলিয়ন আইটেমের সাথে একটি নিম্পি অ্যারে তৈরি করা ভাল এবং তারপরে পুরো অ্যারেটিতে পরিচালনা করা ভাল। এমনকি যদি আপনি একটি সীমাবদ্ধ পার্থক্য পদ্ধতি বা ফলাফলটি পূর্ববর্তী ফলাফলের উপর নির্ভর করে এমন কিছু করে থাকেন তবে আপনি কখনও কখনও এটি করতে পারেন। (কখনও কখনও জোর দেওয়া ...) যে কোনও হারে, গতি যদি প্রাথমিক লক্ষ্য হয় তবে দুর্গটি এখনও রাজা। f2pyতোমার বন্ধু! একটি অ্যালগরিদমের পারফরম্যান্স সমালোচনামূলক অংশগুলি (বিশেষত বৈজ্ঞানিক কম্পিউটিংয়ে) অন্য ভাষায় লিখতে এবং পাইথন থেকে কল করা প্রায়শই সার্থক। শুভকামনা!
জো কিংটন

1
@berto। এটি ধীরে ধীরে এটির জন্য একটি মোড়ক arr[::-1]: github.com/numpy/numpy/blob/master/numpy/lib/twodim_base.py । জন্য অনুসন্ধান করুন def flipud। ফাংশনটি আক্ষরিকভাবে চার লাইন দীর্ঘ।
পাগল পদার্থবিদ 5

উত্তর:


239

আপনি যখন তৈরি করবেন reversed_arrআপনি মূল অ্যারেতে একটি ভিউ তৈরি করছেন। তারপরে আপনি আসল অ্যারে পরিবর্তন করতে পারবেন এবং পরিবর্তনগুলি প্রতিফলিত করতে ভিউ আপডেট হবে।

আপনি নিজের প্রয়োজনের চেয়ে বেশি বার ভিউ তৈরি করছেন? আপনার এমন কিছু করতে সক্ষম হওয়া উচিত:

arr = np.array(some_sequence)
reversed_arr = arr[::-1]

do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)

আমি কোনও ছদ্মবেশী বিশেষজ্ঞ নই, তবে মনে হচ্ছে এটি শূন্যে জিনিসগুলি করার সবচেয়ে দ্রুততম উপায়। আপনি যদি ইতিমধ্যে এটি করছেন তবে আমার মনে হয় না আপনি এতে উন্নতি করতে পারেন।

পিএস এখানে অদ্ভুত দর্শনগুলির দুর্দান্ত আলোচনা:

একটি অদ্ভুত অ্যারে দেখুন?


এটি কোনও স্লাইস অবজেক্ট তৈরি করতে এবং তারপরে এটি অনেক অ্যারে পুনরায় ব্যবহার করতে সহায়তা করে?
এন্ডোলিথ

1
প্রকৃতপক্ষে আমি এটি কেবল পরীক্ষা করেছি এবং লুপের বাইরে স্লাইস অবজেক্টের সাথে কোনও পার্থক্য দেখছি না। (ওহ অপেক্ষা করুন, এটি খুব সামান্য দ্রুত Rep 4300 এমএস বনাম 44.3 এমএস 1000000 লুপের জন্য)
এন্ডোলিথ

look_atধরুন ফাংশনটি কী করতে হবে?
mrgloom

1
@ এমআরগ্লুম এটি কোনও কাজকে উপাত্ত দেখায় তা উপস্থাপন করার কথা। উদাহরণের মূল বিষয়টি দেখানো হয়েছিল যে reversed_arrঅন্তর্নিহিত ডেটা পরিবর্তিত হওয়ার পরেও দৃশ্যটি এখনও ব্যবহারযোগ্য। অ্যারেতে নতুন মান লিখলে দর্শনটি অকার্যকর হয় না। আসলে আপনি অ্যারেতে নতুন মান লেখার জন্য ভিউটিও ব্যবহার করতে পারেন। reversed_arr[0] = 99অ্যারেতে শেষ উপাদানটি 99 তে সেট করবে, যেমনটি arr[-1] = 99হবে।
স্টিভেহা

60

উপরে উল্লিখিত হিসাবে, a[::-1]সত্যই কেবল একটি দর্শন তৈরি করে, সুতরাং এটি একটি ধ্রুবক-সময় অপারেশন (এবং যেমন অ্যারে বড় হওয়ার সাথে সাথে বেশি সময় নেয় না)। আপনি অ্যারের প্রয়োজন সংলগ্ন হতে (উদাহরণস্বরূপ কারণ আপনি এটি দিয়ে অনেক ভেক্টর অপারেশন সম্পাদন করছি), ascontiguousarrayসম্পর্কে যত দ্রুত হয় flipup/ fliplr:

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


প্লট তৈরির কোড:

import numpy
import perfplot


perfplot.show(
    setup=lambda n: numpy.random.randint(0, 1000, n),
    kernels=[
        lambda a: a[::-1],
        lambda a: numpy.ascontiguousarray(a[::-1]),
        lambda a: numpy.fliplr([a])[0],
    ],
    labels=["a[::-1]", "ascontiguousarray(a[::-1])", "fliplr"],
    n_range=[2 ** k for k in range(25)],
    xlabel="len(a)",
    logx=True,
    logy=True,
)

পারফপ্লটের জন্য কমপক্ষে পাইথন ৩.6 প্রয়োজন কারণ এটি এফ-স্ট্রিংগুলি ব্যবহার করে (লিটারাল স্ট্রিং ইন্টারপোলেশন)

42

কারণ এটি এখনও উত্তর হিসাবে চিহ্নিত করা হয়নি বলে মনে হচ্ছে ... থমাস আরিল্ডসনের উত্তর সঠিক হওয়া উচিত: কেবল ব্যবহার

np.flipud(your_array) 

এটি যদি 1 ডি অ্যারে হয় (কলাম অ্যারে)।

ম্যাট্রিজেস দিয়ে

fliplr(matrix)

আপনি যদি সারিগুলি বিপরীত করতে চান এবং flipud(matrix)যদি আপনি কলামগুলি ফ্লিপ করতে চান। আপনার 1 ডি কলাম অ্যারেকে 2-মাত্রিক সারি অ্যারে তৈরি করার দরকার নেই (ম্যাট্রিক্স একটি নন লেয়ার নেই) এবং তারপরে এটি উল্টান।


38

np.fliplr() অ্যারে থেকে বামে ডানদিকে উল্টান।

মনে রাখবেন যে 1 ডি অ্যারেগুলির জন্য, আপনাকে এটি কিছুটা চালিত করতে হবে:

arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]

34
reversed_arr = np.flipud(arr1d)সরাসরি কাজ বলে মনে হচ্ছে।
থমাস আরিল্ডসেন

3

আমি পূর্ববর্তী উত্তর সম্পর্কে প্রসারিত করব np.fliplr()। এখানে এমন কিছু কোড রয়েছে যা একটি 1 ডি অ্যারে তৈরি করে এটি 2d ​​অ্যারে রূপান্তর করে, উল্টিয়ে ফিরছে এবং তারপরে আবার 1d অ্যারে রূপান্তরিত করে। time.clock()সময় রাখতে ব্যবহৃত হবে, যা সেকেন্ডের শর্তে উপস্থাপিত হয়।

import time
import numpy as np

start = time.clock()
x = np.array(range(3))
#transform to 2d
x = np.atleast_2d(x)
#flip array
x = np.fliplr(x)
#take first (and only) element
x = x[0]
#print x
end = time.clock()
print end-start

নিরবচ্ছিন্ন মুদ্রণ বিবৃতি সহ:

[2 1 0]
0.00203907123594

মুদ্রণ বিবৃতি মন্তব্য সহ:

5.59799927506e-05

সুতরাং, দক্ষতার দিক থেকে, আমি মনে করি এটি শালীন। আপনার মধ্যে যারা এটি এক লাইনে করতে পছন্দ করেন তাদের জন্য এখানে এই ফর্মটি রয়েছে।

np.fliplr(np.atleast_2d(np.array(range(3))))[0]

3
এত ছোট অ্যারে দিয়ে কোনও কিছুর সময় নির্ধারণ করা বেশ বেহুদা। আপনি যদি জিনিসগুলির তুলনা করতে চান তবে 3000 বা আরও বেশি উপাদানগুলির মতো কিছুটা সময় নেয় এমন কিছু ব্যবহার করা ভাল।
বড়বাস

0

অন্যেরা যা বলেছে সে সম্পর্কে বিস্তৃত করার জন্য আমি একটি ছোট উদাহরণ দেব।

আপনার যদি 1 ডি অ্যারে থাকে ...

>>> import numpy as np
>>> x = np.arange(4) # array([0, 1, 2, 3])
>>> x[::-1] # returns a view
Out[1]: 
array([3, 2, 1, 0])

তবে আপনি যদি 2 ডি অ্যারে নিয়ে কাজ করছেন ...

>>> x = np.arange(10).reshape(2, 5)
>>> x
Out[2]:
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

>>> x[::-1] # returns a view:
Out[3]: array([[5, 6, 7, 8, 9],
               [0, 1, 2, 3, 4]])

এটি আসলে ম্যাট্রিক্সকে বিপরীত করে না।

উপাদানগুলিকে রিভার্স করার জন্য np.flip ব্যবহার করা উচিত

>>> np.flip(x)
Out[4]: array([[9, 8, 7, 6, 5],
               [4, 3, 2, 1, 0]])

আপনি যদি একটি ম্যাট্রিক্সের উপাদানগুলি একের পর এক ফ্ল্যাটের সাথে ফ্ল্যাটের সাথে মুদ্রণ করতে চান

>>> for el in np.flip(x).flat:
>>>     print(el, end = ' ')
9 8 7 6 5 4 3 2 1 0

-1

এটি নেতিবাচক সংখ্যা এবং একটি দীর্ঘ তালিকা দিয়ে কাজ করার জন্য আপনি নিম্নলিখিতটি করতে পারেন:

b = numpy.flipud(numpy.array(a.split(),float))

যেখানে ফ্লিপড 1 ডি আরার জন্য

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