আমি কীভাবে "ফর-লুপ" স্কুল থেকে সরে যেতে পারি?


79

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

আমি জানি যে NumPy এর সাথে অনেক কিছুর জন্য প্রাক-সংজ্ঞায়িত কমান্ড রয়েছে যা আমার কেবল গবেষণা করা দরকার তবে আপনি (আরও অভিজ্ঞ প্রোগ্রামার হিসাবে) আপনার মনে একটি সাধারণ চিন্তার প্রক্রিয়া রয়েছে যা আপনাকে কিছু পুনরুক্তি করতে হবে?

তাই আমার প্রায়শই এরকম কিছু থাকে যা ভয়াবহ এবং আমি এড়াতে চাই:

small_array = np.array(["one", "two"])
big_array = np.array(["one", "two", "three", "one"])

for i in range(len(small_array)):
    for p in range(len(big_array)):
        if small_array[i] == big_array[p]:
            print "This item is matched: ", small_array[i]

আমি জানি যে এটি বিশেষত অর্জন করার জন্য বিভিন্ন ধরণের উপায় রয়েছে তবে আমি যদি চিন্তা করি তবে একটি সাধারণ পদ্ধতিতে যদি এটি বিদ্যমান থাকে তবে আমি আগ্রহী।


10
আপনি কার্যকরী প্রোগ্রামিং সন্ধান করছেন : ল্যাম্বডা এক্সপ্রেশন, উচ্চ-অর্ডার ফাংশন, এক্সপ্রেশন উত্পন্ন করা ইত্যাদি গুগল those
কিলিয়ান ফথ 26'14 এ 12

42
I want to avoid for-loops as much as possible because they are slow (at least in Python).মনে হচ্ছে আপনি এখানে ভুল সমস্যাটি সমাধান করছেন। আপনার যদি কোনও কিছুর উপরে পুনরাবৃত্তি করতে হয় তবে আপনাকে কোনও কিছুর উপরে পুনরাবৃত্তি করতে হবে; আপনি যে পাইথনটি ব্যবহার করেন তা বিবেচনা না করে আপনি একইরকম পারফরম্যান্স গ্রহণ করবেন। যদি আপনার কোডটি ধীর হয় তবে এটি আপনার forলুপ নেই বলে নয় ; এর কারণ আপনি অপ্রয়োজনীয় কাজ করছেন বা পাইথন সাইডে কাজ করছেন যা সি দিকে করা যেতে পারে। আপনার উদাহরণে আপনি অতিরিক্ত কাজ করছেন; আপনি দুটির পরিবর্তে একটি লুপ দিয়ে এটি করতে পারতেন।
ডোভাল

24
দুর্ভাগ্যবশত না @Doval - NumPy মধ্যে । লুফ সম্পাদনকারী উপাদানটির পরিবর্তনের জন্য পাইথনটি ভেক্টরাইজড নম্পপি অপারেটরের (যা কেবল সি তে লেখা হয় না তবে এসএসই নির্দেশাবলী এবং অন্যান্য কৌশল ব্যবহার করে) রিয়েলস্টিকাল অ্যারের আকারের জন্য সহজেই কয়েকগুণ (!) ধীর হতে পারে।

46
উপরের কিছু মন্তব্য প্রশ্নের ভুল বোঝায়। নুমপি-তে প্রোগ্রামিং করার সময়, আপনি যদি নিজের গণনাকে ভেক্টরাইজ করতে পারেন তবে আপনি সেরা ফলাফল পাবেন - অর্থাত পাইথনের স্পষ্ট লুপগুলি নুমপিতে পুরো-অ্যারে ক্রিয়াকলাপের সাথে প্রতিস্থাপন করুন। এটি পাইথনের সাধারণ প্রোগ্রামিং থেকে ধারণাগতভাবে খুব আলাদা এবং এটি শিখতে সময় লাগে। সুতরাং আমি মনে করি যে ওপির কীভাবে এটি শিখতে হবে সে সম্পর্কে পরামর্শ জিজ্ঞাসা করা যুক্তিসঙ্গত।
গ্যারেথ রিস ২

3
@ পিটারবি: হ্যাঁ, ঠিক আছে। "সেরা অ্যালগরিদম নির্বাচন করা" "ভেক্টরাইজেশন" সমান নয়। এগুলি দক্ষ বাস্তবায়ন নিয়ে আসতে অসুবিধার দুটি পৃথক উত্স এবং তাই তাদের একবারে একবারে চিন্তা করা ভাল।
গ্যারেথ রিস ২

উত্তর:


89

কার্যকরভাবে NumPy ব্যবহার করতে শেখার সময় এটি একটি সাধারণ ধারণাগত সমস্যা । সাধারণত, পাইথনে ডেটা প্রসেসিংটি পুনরাবৃত্তির ক্ষেত্রে , মেমরির ব্যবহার কম রাখার জন্য, I / O সিস্টেমের সাথে সমান্তরালতার সর্বাধিক সুযোগ তৈরি করার জন্য এবং অ্যালগোরিদমের অংশগুলির পুনরায় ব্যবহার এবং সংমিশ্রনের জন্য সরবরাহ করার ক্ষেত্রে সর্বোত্তমভাবে প্রকাশ করা হয়।

তবে নুমপি সব কিছু ভিতরে ভিতরে ঘুরিয়ে দেয়: অলগরিদমকে পুরো-অ্যারে ক্রিয়াকলাপ হিসাবে স্লো পাইথন ইন্টারপ্রেটারে ব্যয় করা সময়ের পরিমাণ কমিয়ে আনা এবং দ্রুত সংকলিত নুমপাই রুটিনগুলিতে ব্যয় করা সময়ের পরিমাণকে সর্বাধিকতম করার জন্য সর্বোত্তম পন্থা।

আমি যে সাধারণ পদ্ধতি গ্রহণ করি তা এখানে:

  1. ফাংশনের আসল সংস্করণটি রাখুন (যা আপনি আত্মবিশ্বাসী যে সঠিক) আপনার যথাযথতা এবং গতি উভয়ের জন্য আপনি এটি আপনার উন্নত সংস্করণগুলির বিরুদ্ধে পরীক্ষা করতে পারেন।

  2. ভিতরে থেকে বাইরে কাজ করুন: এটি হ'ল ভিতরের লুপটি দিয়ে শুরু করুন এবং দেখুন ভেক্টরাইজড করা যায় কিনা; তারপরে আপনি যখন এটি করেন, তখন একটি স্তর সরে যান এবং চালিয়ে যান।

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

অনুশীলনের বিকল্প নেই, তাই আমি আপনাকে কয়েকটি উদাহরণের সমস্যা দিতে যাচ্ছি। প্রতিটি সমস্যার লক্ষ্য হ'ল ফাংশনটি পুনরায় রচনা করা যাতে এটি সম্পূর্ণরূপে ভেক্টরাইজড হয় : এটি হ'ল এটি সম্পূর্ণ অ্যারেগুলিতে NumPy ক্রিয়াকলাপের সমন্বিত থাকে, কোনও নেটিভ পাইথন লুপ (কোনও forবা whileবিবৃতি, কোনও পুনরাবৃত্তি বা বোঝার) নেই।

সমস্যা ঘ

def sumproducts(x, y):
    """Return the sum of x[i] * y[j] for all pairs of indices i, j.

    >>> sumproducts(np.arange(3000), np.arange(3000))
    20236502250000

    """
    result = 0
    for i in range(len(x)):
        for j in range(len(y)):
            result += x[i] * y[j]
    return result

সমস্যা 2

def countlower(x, y):
    """Return the number of pairs i, j such that x[i] < y[j].

    >>> countlower(np.arange(0, 200, 2), np.arange(40, 140))
    4500

    """
    result = 0
    for i in range(len(x)):
        for j in range(len(y)):
            if x[i] < y[j]:
                result += 1
    return result

সমস্যা 3

def cleanup(x, missing=-1, value=0):
    """Return an array that's the same as x, except that where x ==
    missing, it has value instead.

    >>> cleanup(np.arange(-3, 3), value=10)
    ... # doctest: +NORMALIZE_WHITESPACE
    array([-3, -2, 10, 0, 1, 2])

    """
    result = []
    for i in range(len(x)):
        if x[i] == missing:
            result.append(value)
        else:
            result.append(x[i])
    return np.array(result)

নীচে Spoilers। আমার সমাধানগুলি দেখার আগে যদি আপনি নিজেই যান তবে আপনি অনেক ভাল ফলাফল পাবেন!

উত্তর 1

np.sum (x) * np.sum (y)

উত্তর 2

এনপি.সাম (এনপি.সার্কসোর্টড (এনপি.সোর্ট (এক্স), y))

উত্তর 3

এনপি.হোহেন (এক্স == অনুপস্থিত, মান, এক্স)


অপেক্ষা করুন, শেষ উত্তরের একটি টাইপো আছে বা নুমপি কীভাবে পাইথন কোডটি ব্যাখ্যা করে তা সংশোধন করে?
ইজকাটা

1
@ ইজকাটা এটি প্রতি সেফের কোনও কিছুই সংশোধন করে না, তবে অ্যারেগুলিতে প্রয়োগ করা লজিকাল অপারেশনগুলি বুলিয়ান অ্যারে ফিরিয়ে দেওয়ার জন্য সংজ্ঞায়িত করা হয়।
sapi

@ সাপি আহা, ডক্টেটেগুলিতে কী চলছে তা আমি ভুলে গেছি, ভেবেছিলাম সেগুলি সরল ছিলlist
ইজকাটা ২

এপিএল এম্বেড করার কোনও উপায় থাকতে পারে?

আপনি কিভাবে হোমওয়ার্ক দেয় আমি পছন্দ করি।
Koray Tugay

8

জিনিসগুলি দ্রুত করার জন্য আপনাকে আপনার ডেটা স্ট্রাকচারগুলি পড়তে হবে এবং উপযুক্তগুলি ব্যবহার করতে হবে।

ছোট অ্যারে এবং বড় অ্যারেগুলির তুচ্ছ আকারের জন্য (আসুন ছোট = 100 উপাদান এবং বড় = 10.000 উপাদানগুলি বলি) এটি করার এক উপায় হ'ল ছোট অ্যারেটিকে সাজানো, তারপরে বড়-অ্যারেতে পুনরাবৃত্তি করা এবং মেলানো উপাদানগুলি খুঁজতে বাইনারি অনুসন্ধান ব্যবহার করুন ছোট অ্যারে।

এটি সর্বাধিক সময়ের জটিলতা তৈরি করবে, হে (এন লগ এন) (এবং ছোট ছোট অ্যারে এবং খুব বড় বড় অ্যারেগুলির জন্য এটি ও (এন)) এর নিকটবর্তী যেখানে আপনার নেস্টেড লুপ দ্রবণটি ও (এন ^ 2)

যাহোক. কোন ডেটা স্ট্রাকচার সবচেয়ে কার্যকর তা প্রকৃত সমস্যার উপর নির্ভর করে।


-3

আপনি পারফরম্যান্স উল্লেখযোগ্যভাবে অনুকূল করতে একটি অভিধান ব্যবহার করতে পারেন

এটি অন্য একটি উদাহরণ:

locations = {}
for i in range(len(airports)):
    locations[airports["abb"][i][1:-1]] = (airports["height"][i], airports["width"][i])

for i in range(len(uniqueData)):
    h, w = locations[uniqueData["dept_apt"][i]]
    uniqueData["dept_apt_height"][i] = h
    uniqueData["dept_apt_width"][i] = w

2
এটি বেশ পরিষ্কারভাবে এখনও "ফর-লুপ" স্কুল অফ চিন্তার ব্যবহার করছে।
বিট্রি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.