X এবং y অ্যারের কার্টেসিয়ান পণ্য 2D পয়েন্টের একক অ্যারেতে পয়েন্ট করে


147

আমার কাছে দুটি নিম্পের অ্যারে রয়েছে যা গ্রিডের x এবং y অক্ষকে সংজ্ঞায়িত করে। উদাহরণ স্বরূপ:

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

আমি উত্পন্ন করতে এই অ্যারের কার্টেসিয়ান পণ্য উত্পন্ন করতে চাই:

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

একটি উপায় যে এটি মারাত্মকভাবে অক্ষম নয় যেহেতু আমাকে লুপে অনেক বার এটি করা দরকার। আমি ধরে নিচ্ছি যে এগুলিকে একটি পাইথন তালিকায় রূপান্তর করা itertools.productএবং একটি অদ্ভুত অ্যারে ব্যবহার করে ফিরে আসা সর্বাধিক দক্ষ ফর্ম নয়।


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

উত্তর:


88
>>> numpy.transpose([numpy.tile(x, len(y)), numpy.repeat(y, len(x))])
array([[1, 4],
       [2, 4],
       [3, 4],
       [1, 5],
       [2, 5],
       [3, 5]])

এন অ্যারে এর কার্টেসিয়ান প্রোডাক্ট গণনা করার জন্য একটি সাধারণ সমাধানের জন্য দুটি অ্যারের সমস্ত সংমিশ্রণের একটি অ্যারে তৈরি করতে ন্যাপি ব্যবহার করে দেখুন ।


1
এই পদ্ধতির একটি সুবিধা হ'ল এটি একই আকারের অ্যারেগুলির জন্য সামঞ্জস্যপূর্ণ আউটপুট উত্পাদন করে। meshgrid+ + dstackপদ্ধতির, যখন দ্রুত কিছু ক্ষেত্রে, বাগ হতে পারে যদি আপনি আশা করতে কার্টিজিয়ান পণ্য একই আকারের অ্যারে জন্য একই আদেশ নির্মাণ করতে হবে।
tlnagy

3
@tlnagy, আমি যে কোন ক্ষেত্রে যেখানে এই পদ্ধতির দ্বারা উত্পাদিত থেকে ভিন্ন ফলাফল উৎপন্ন খেয়াল করেন নি meshgrid+ + dstack। আপনি একটি উদাহরণ পোস্ট করতে পারেন?
প্রেরক

148

একটি আধ্যাত্মিক cartesian_product(প্রায়)

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

এই উত্তরটি দেওয়া হয়েছে, কারটিশিয়ান পণ্যটির বিষয়ে এটি সম্পর্কে আমি সচেতন যে এটি এখন আর দ্রুত বাস্তবায়ন নয় numpy। তবে আমি মনে করি এর সরলতা ভবিষ্যতের উন্নতির জন্য এটি একটি কার্যকর মানদণ্ড হিসাবে অবিরত থাকবে:

def cartesian_product(*arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[...,i] = a
    return arr.reshape(-1, la)

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

উল্লেখযোগ্য বিকল্প

ফোর্টরান ক্রমে মেমরির সংকীর্ণ ব্লকগুলি লেখার জন্য এটি কখনও কখনও দ্রুত। এটি এই বিকল্পের ভিত্তি cartesian_product_transpose, যা কিছু হার্ডওয়্যার থেকে দ্রুত প্রমাণিত হয়েছে cartesian_product(নীচে দেখুন)। তবে একই নীতিটি ব্যবহার করে পল পাঞ্জেরের উত্তর আরও দ্রুত। তবুও, আমি আগ্রহী পাঠকদের জন্য এটি এখানে অন্তর্ভুক্ত করছি:

def cartesian_product_transpose(*arrays):
    broadcastable = numpy.ix_(*arrays)
    broadcasted = numpy.broadcast_arrays(*broadcastable)
    rows, cols = numpy.prod(broadcasted[0].shape), len(broadcasted)
    dtype = numpy.result_type(*arrays)

    out = numpy.empty(rows * cols, dtype=dtype)
    start, end = 0, rows
    for a in broadcasted:
        out[start:end] = a.reshape(-1)
        start, end = end, end + rows
    return out.reshape(cols, rows).T

পানজারের পদ্ধতির বিষয়টি বুঝতে পেরে, আমি একটি নতুন সংস্করণ লিখেছিলাম যা তার চেয়ে প্রায় দ্রুত এবং এটি প্রায় সহজ cartesian_product:

def cartesian_product_simple_transpose(arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([la] + [len(a) for a in arrays], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[i, ...] = a
    return arr.reshape(la, -1).T

এটিতে কিছু ধ্রুবক-সময় ওভারহেড উপস্থিত রয়েছে যা এটি ছোট ইনপুটগুলির জন্য পানজারের চেয়ে ধীর গতিতে চালিত করে। তবে বৃহত্তর ইনপুটগুলির জন্য, আমি যে সমস্ত পরীক্ষাগুলি চালিয়েছি, এটি তার দ্রুত বাস্তবায়ন ( cartesian_product_transpose_pp) হিসাবে সম্পাদন করে ।

নিম্নলিখিত বিভাগগুলিতে, আমি অন্যান্য বিকল্পের কয়েকটি পরীক্ষা অন্তর্ভুক্ত করছি। এগুলি এখন কিছুটা পুরানো, তবে সদৃশ প্রচেষ্টার চেয়ে আমি এগুলি এখানে historicalতিহাসিক আগ্রহের বাইরে রেখেই যাওয়ার সিদ্ধান্ত নিয়েছি। আপ-টু-ডেট পরীক্ষাগুলির জন্য পানজারের উত্তরও দেখুন পানজারের নিকো স্ক্ল্যামার এর দেখুন।

বিকল্পের বিরুদ্ধে টেস্ট

এখানে পরীক্ষাগুলির একটি ব্যাটারি রয়েছে যা পারফরম্যান্সের বুস্ট দেখায় যে এই কয়েকটি ফাংশন বিভিন্ন বিকল্পের সাথে সম্পর্কিত করে। এখানে প্রদর্শিত সমস্ত পরীক্ষাগুলি ম্যাক ওএস 10.12.5, পাইথন 3.6.1 এবং চলমান কোয়াড-কোর মেশিনে সঞ্চালিত হয়েছিল এবংnumpy 1.12.1 । হার্ডওয়্যার এবং সফ্টওয়্যার এর পার্থক্য বিভিন্ন ফলাফল উত্পাদন হিসাবে পরিচিত, তাই ওয়াইএমএমভি। নিজের নিশ্চিত হওয়ার জন্য এই পরীক্ষাগুলি চালান!

সজ্ঞা:

import numpy
import itertools
from functools import reduce

### Two-dimensional products ###

def repeat_product(x, y):
    return numpy.transpose([numpy.tile(x, len(y)), 
                            numpy.repeat(y, len(x))])

def dstack_product(x, y):
    return numpy.dstack(numpy.meshgrid(x, y)).reshape(-1, 2)

### Generalized N-dimensional products ###

def cartesian_product(*arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[...,i] = a
    return arr.reshape(-1, la)

def cartesian_product_transpose(*arrays):
    broadcastable = numpy.ix_(*arrays)
    broadcasted = numpy.broadcast_arrays(*broadcastable)
    rows, cols = numpy.prod(broadcasted[0].shape), len(broadcasted)
    dtype = numpy.result_type(*arrays)

    out = numpy.empty(rows * cols, dtype=dtype)
    start, end = 0, rows
    for a in broadcasted:
        out[start:end] = a.reshape(-1)
        start, end = end, end + rows
    return out.reshape(cols, rows).T

# from https://stackoverflow.com/a/1235363/577088

def cartesian_product_recursive(*arrays, out=None):
    arrays = [numpy.asarray(x) for x in arrays]
    dtype = arrays[0].dtype

    n = numpy.prod([x.size for x in arrays])
    if out is None:
        out = numpy.zeros([n, len(arrays)], dtype=dtype)

    m = n // arrays[0].size
    out[:,0] = numpy.repeat(arrays[0], m)
    if arrays[1:]:
        cartesian_product_recursive(arrays[1:], out=out[0:m,1:])
        for j in range(1, arrays[0].size):
            out[j*m:(j+1)*m,1:] = out[0:m,1:]
    return out

def cartesian_product_itertools(*arrays):
    return numpy.array(list(itertools.product(*arrays)))

### Test code ###

name_func = [('repeat_product',                                                 
              repeat_product),                                                  
             ('dstack_product',                                                 
              dstack_product),                                                  
             ('cartesian_product',                                              
              cartesian_product),                                               
             ('cartesian_product_transpose',                                    
              cartesian_product_transpose),                                     
             ('cartesian_product_recursive',                           
              cartesian_product_recursive),                            
             ('cartesian_product_itertools',                                    
              cartesian_product_itertools)]

def test(in_arrays, test_funcs):
    global func
    global arrays
    arrays = in_arrays
    for name, func in test_funcs:
        print('{}:'.format(name))
        %timeit func(*arrays)

def test_all(*in_arrays):
    test(in_arrays, name_func)

# `cartesian_product_recursive` throws an 
# unexpected error when used on more than
# two input arrays, so for now I've removed
# it from these tests.

def test_cartesian(*in_arrays):
    test(in_arrays, name_func[2:4] + name_func[-1:])

x10 = [numpy.arange(10)]
x50 = [numpy.arange(50)]
x100 = [numpy.arange(100)]
x500 = [numpy.arange(500)]
x1000 = [numpy.arange(1000)]

পরীক্ষার ফলাফল:

In [2]: test_all(*(x100 * 2))
repeat_product:
67.5 µs ± 633 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
dstack_product:
67.7 µs ± 1.09 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
cartesian_product:
33.4 µs ± 558 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
cartesian_product_transpose:
67.7 µs ± 932 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
cartesian_product_recursive:
215 µs ± 6.01 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
cartesian_product_itertools:
3.65 ms ± 38.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [3]: test_all(*(x500 * 2))
repeat_product:
1.31 ms ± 9.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
dstack_product:
1.27 ms ± 7.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
cartesian_product:
375 µs ± 4.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
cartesian_product_transpose:
488 µs ± 8.88 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
cartesian_product_recursive:
2.21 ms ± 38.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_itertools:
105 ms ± 1.17 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [4]: test_all(*(x1000 * 2))
repeat_product:
10.2 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
dstack_product:
12 ms ± 120 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product:
4.75 ms ± 57.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_transpose:
7.76 ms ± 52.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_recursive:
13 ms ± 209 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_itertools:
422 ms ± 7.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

সব ক্ষেত্রে, cartesian_product এই উত্তরটির শুরুতে সংজ্ঞায়িত হিসাবে দ্রুততম।

যে ফাংশনগুলি ইনপুট অ্যারেগুলির একটি স্বেচ্ছাসেবী সংখ্যার স্বীকৃতি দেয়, তাদের জন্য যখন এটি পরীক্ষা len(arrays) > 2করা ভাল হয় performance (যতক্ষণ না আমি নির্ধারণ করতে পারি যে কেন cartesian_product_recursiveএই ক্ষেত্রে ত্রুটি ছুঁড়েছে, আমি এগুলি এই পরীক্ষাগুলি থেকে সরিয়েছি))

In [5]: test_cartesian(*(x100 * 3))
cartesian_product:
8.8 ms ± 138 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_transpose:
7.87 ms ± 91.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_itertools:
518 ms ± 5.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [6]: test_cartesian(*(x50 * 4))
cartesian_product:
169 ms ± 5.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
cartesian_product_transpose:
184 ms ± 4.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
cartesian_product_itertools:
3.69 s ± 73.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [7]: test_cartesian(*(x10 * 6))
cartesian_product:
26.5 ms ± 449 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
cartesian_product_transpose:
16 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
cartesian_product_itertools:
728 ms ± 16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [8]: test_cartesian(*(x10 * 7))
cartesian_product:
650 ms ± 8.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
cartesian_product_transpose:
518 ms ± 7.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
cartesian_product_itertools:
8.13 s ± 122 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

যেমন এই পরীক্ষাগুলি দেখায়, cartesian_productইনপুট অ্যারেগুলির সংখ্যা চারটির উপরে না বাড়ানো পর্যন্ত প্রতিযোগিতামূলক থেকে যায়। তারপর,cartesian_product_transpose একটি সামান্য প্রান্ত আছে।

এটি পুনরাবৃত্তি করার মতো যে অন্যান্য হার্ডওয়্যার এবং অপারেটিং সিস্টেমের ব্যবহারকারীরা বিভিন্ন ফলাফল দেখতে পারেন। উদাহরণস্বরূপ, উবুন্টু 14.04, পাইথন numpy3.4.3 , এবং 1.14.0.dev0 + বি 7050a9 ব্যবহার করে এই পরীক্ষাগুলির জন্য নিম্নলিখিত ফলাফলগুলি দেখার জন্য আনটবু রিপোর্ট করেছে:

>>> %timeit cartesian_product_transpose(x500, y500) 
1000 loops, best of 3: 682 µs per loop
>>> %timeit cartesian_product(x500, y500)
1000 loops, best of 3: 1.55 ms per loop

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

একটি সহজ বিকল্প: meshgrid+dstack

বর্তমানে উত্তর ব্যবহারসমূহ গৃহীত tileএবং repeatসম্প্রচারের দুই অ্যারে একসঙ্গে। তবে meshgridফাংশনটি কার্যত একই জিনিসটি করে। স্থানান্তর করতে পাস করার আগে tileএবং এর repeatআগে আউটপুট দেওয়া হয়:

In [1]: import numpy
In [2]: x = numpy.array([1,2,3])
   ...: y = numpy.array([4,5])
   ...: 

In [3]: [numpy.tile(x, len(y)), numpy.repeat(y, len(x))]
Out[3]: [array([1, 2, 3, 1, 2, 3]), array([4, 4, 4, 5, 5, 5])]

এবং এখানে ফলাফল meshgrid:

In [4]: numpy.meshgrid(x, y)
Out[4]: 
[array([[1, 2, 3],
        [1, 2, 3]]), array([[4, 4, 4],
        [5, 5, 5]])]

আপনি দেখতে পাচ্ছেন, এটি প্রায় অভিন্ন। হুবহু একই ফলাফল পেতে আমাদের কেবল পুনরায় আকার পরিবর্তন করতে হবে।

In [5]: xt, xr = numpy.meshgrid(x, y)
   ...: [xt.ravel(), xr.ravel()]
Out[5]: [array([1, 2, 3, 1, 2, 3]), array([4, 4, 4, 5, 5, 5])]

এই মুহুর্তে পুনর্নির্মাণের পরিবর্তে, আমরা এর ফলাফল আউটপুটটি এবং পরে পুনরায় আকার meshgridদিতে পারলাম dstackযা কিছু কাজ সাশ্রয় করে:

In [6]: numpy.dstack(numpy.meshgrid(x, y)).reshape(-1, 2)
Out[6]: 
array([[1, 4],
       [2, 4],
       [3, 4],
       [1, 5],
       [2, 5],
       [3, 5]])

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

পরীক্ষা meshgrid+ dstackবনাম repeat+transpose

এই দুটি পদ্ধতির আপেক্ষিক কর্মক্ষমতা সময়ের সাথে পরিবর্তিত হয়েছে। পাইথনের পূর্ববর্তী সংস্করণে (২.)), meshgrid+ এর ফলাফলটি dstackছোট ইনপুটগুলির জন্য লক্ষণীয়ভাবে দ্রুততর হয়েছিল। (দ্রষ্টব্য যে এই পরীক্ষাগুলি এই উত্তরের একটি পুরানো সংস্করণ থেকে এসেছে)) সংজ্ঞা:

>>> def repeat_product(x, y):
...     return numpy.transpose([numpy.tile(x, len(y)), 
                                numpy.repeat(y, len(x))])
...
>>> def dstack_product(x, y):
...     return numpy.dstack(numpy.meshgrid(x, y)).reshape(-1, 2)
...     

মাঝারি আকারের ইনপুটটির জন্য, আমি একটি উল্লেখযোগ্য স্পিডআপ দেখেছি। তবে আমি পাইথনের আরও সাম্প্রতিক সংস্করণ (3.6.1) এবং numpy(1.12.1) এর সাথে একটি নতুন মেশিনে এই পরীক্ষাগুলি পুনরায় চেষ্টা করেছি । দুটি পদ্ধতির এখন প্রায় অভিন্ন।

ওল্ড টেস্ট

>>> x, y = numpy.arange(500), numpy.arange(500)
>>> %timeit repeat_product(x, y)
10 loops, best of 3: 62 ms per loop
>>> %timeit dstack_product(x, y)
100 loops, best of 3: 12.2 ms per loop

নতুন পরীক্ষা

In [7]: x, y = numpy.arange(500), numpy.arange(500)
In [8]: %timeit repeat_product(x, y)
1.32 ms ± 24.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [9]: %timeit dstack_product(x, y)
1.26 ms ± 8.47 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

বরাবরের মতো, ওয়াইএমএমভি, তবে এটি সূচিত করে যে পাইথন এবং অলস এর সাম্প্রতিক সংস্করণগুলিতে এগুলি বিনিময়যোগ্য।

সাধারণীকরণ পণ্য ফাংশন

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

প্রাসঙ্গিক পরীক্ষাগুলির বেশিরভাগই এই উত্তরের শুরুতে উপস্থিত হয় তবে পাইথনের পূর্ববর্তী সংস্করণগুলিতে এবং numpyতুলনার জন্য পরীক্ষাগুলির কয়েকটি দেওয়া হল ।

cartesianফাংশন সংজ্ঞায়িত অন্য উত্তর বৃহত্তর ইনপুট জন্য চমত্কার সঞ্চালন করতে ব্যবহৃত। (এটি cartesian_product_recursiveউপরে বর্ণিত ফাংশনটির মতোই ।) এর সাথে তুলনা cartesianকরার জন্য dstack_prodct, আমরা মাত্র দুটি মাত্রা ব্যবহার করি।

এখানে আবারও, পুরানো পরীক্ষাটি একটি উল্লেখযোগ্য পার্থক্য দেখিয়েছে, যখন নতুন পরীক্ষাটি প্রায় কোনওটিই দেখায় না।

ওল্ড টেস্ট

>>> x, y = numpy.arange(1000), numpy.arange(1000)
>>> %timeit cartesian([x, y])
10 loops, best of 3: 25.4 ms per loop
>>> %timeit dstack_product(x, y)
10 loops, best of 3: 66.6 ms per loop

নতুন পরীক্ষা

In [10]: x, y = numpy.arange(1000), numpy.arange(1000)
In [11]: %timeit cartesian([x, y])
12.1 ms ± 199 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [12]: %timeit dstack_product(x, y)
12.7 ms ± 334 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

আগের মতো dstack_productএখনও cartesianছোট আকারের স্কেলে মারধর করে।

নতুন পরীক্ষা ( অপ্রয়োজনীয় পুরাতন পরীক্ষা দেখানো হয়নি )

In [13]: x, y = numpy.arange(100), numpy.arange(100)
In [14]: %timeit cartesian([x, y])
215 µs ± 4.75 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [15]: %timeit dstack_product(x, y)
65.7 µs ± 1.15 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

এই পার্থক্যগুলি হ'ল, আমি মনে করি, আকর্ষণীয় এবং মূল্যবান রেকর্ডিং; তবে শেষ পর্যন্ত তারা একাডেমিক। এই উত্তরের শুরুতে পরীক্ষাগুলি যেমন দেখিয়েছে, এই উত্তরগুলির cartesian_productএকেবারে শুরুতে সংজ্ঞায়িত এই সংস্করণগুলির প্রায় সবসময়ই ধীর ।


1
এবং যোগ করার dtype=objectমধ্যে arr = np.empty( )পণ্য বিভিন্ন ধরনের ব্যবহার করে, যেমন জন্য সম্ভব হবে arrays = [np.array([1,2,3]), ['str1', 'str2']]
ব্যবহারকারীর 3820991

আপনার উদ্ভাবনী সমাধানের জন্য অনেক ধন্যবাদ। ভেবেছিলেন আপনি জানতে চান কিছু ব্যবহারকারী তাদের মেশিন ওএস, পাইথন বা নিম্পী সংস্করণের উপর নির্ভর করে cartesian_product_tranposeদ্রুত খুঁজে পেতে পারেন cartesian_product। উদাহরণস্বরূপ, উবুন্টু 14.04 এ, পাইথন 3.4.3.3, ন্যালি 1.14.0.dev0 + b7050a9, %timeit cartesian_product_transpose(x500,y500)ফলন করার 1000 loops, best of 3: 682 µs per loopসময় %timeit cartesian_product(x500,y500)ফলন দেয় 1000 loops, best of 3: 1.55 ms per loop। আমি cartesian_product_transposeযখন দ্রুত হতে পারে সন্ধান করছি len(arrays) > 2
unutbu

উপরন্তু, cartesian_productফ্লোটিং পয়েন্ট dtype একটি অ্যারের ফেরৎ যখন cartesian_product_transposeআয় প্রথম (সম্প্রচারিত) অ্যারে হিসাবে একই dtype একটি অ্যারে। পূর্ণসংখ্যার অ্যারেগুলির সাথে কাজ করার সময় dtype সংরক্ষণের দক্ষতা ব্যবহারকারীদের পক্ষে উপযুক্ত হতে পারে cartesian_product_transpose
unutbu

@ ইউন্টবু আবার ধন্যবাদ - আমার জানা উচিত, টাইপ ক্লোন করা কেবল সুবিধা যোগ করে না; এটি কিছু ক্ষেত্রে কোডটি আরও 20-30% গতিবেগ করে।
প্রেরক

1
@ সেন্ডারেল: বাহ, দুর্দান্ত! এছাড়াও, এটি আমার কাছে ঘটেছিল যে dtype = np.find_common_type([arr.dtype for arr in arrays], [])প্রথমে dtype নিয়ন্ত্রণ করে ব্যবহারকারীকে অ্যারে রাখতে বাধ্য করার পরিবর্তে সমস্ত অ্যারের সাধারণ টাইপ সন্ধান করার মতো কিছু ব্যবহার করা যেতে পারে।
unutbu

44

আপনি পাইথনে সাধারণ তালিকা বোধগম্যতা করতে পারেন

x = numpy.array([1,2,3])
y = numpy.array([4,5])
[[x0, y0] for x0 in x for y0 in y]

যা তোমাকে দেওয়া উচিত

[[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

28

আমি এটিতেও আগ্রহী ছিলাম এবং সামান্য পারফরম্যান্স তুলনা করেছি, সম্ভবত @ প্রেরকের উত্তরের চেয়ে কিছুটা পরিষ্কার।

দুটি অ্যারে (শাস্ত্রীয় ক্ষেত্রে) এর জন্য:

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

চারটি অ্যারের জন্য:

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

(দ্রষ্টব্য যে অ্যারেগুলির দৈর্ঘ্য এখানে কয়েক ডজন এন্ট্রি রয়েছে))


প্লটগুলি পুনরুত্পাদন করার কোড:

from functools import reduce
import itertools
import numpy
import perfplot


def dstack_product(arrays):
    return numpy.dstack(numpy.meshgrid(*arrays, indexing="ij")).reshape(-1, len(arrays))


# Generalized N-dimensional products
def cartesian_product(arrays):
    la = len(arrays)
    dtype = numpy.find_common_type([a.dtype for a in arrays], [])
    arr = numpy.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[..., i] = a
    return arr.reshape(-1, la)


def cartesian_product_transpose(arrays):
    broadcastable = numpy.ix_(*arrays)
    broadcasted = numpy.broadcast_arrays(*broadcastable)
    rows, cols = reduce(numpy.multiply, broadcasted[0].shape), len(broadcasted)
    dtype = numpy.find_common_type([a.dtype for a in arrays], [])

    out = numpy.empty(rows * cols, dtype=dtype)
    start, end = 0, rows
    for a in broadcasted:
        out[start:end] = a.reshape(-1)
        start, end = end, end + rows
    return out.reshape(cols, rows).T


# from https://stackoverflow.com/a/1235363/577088
def cartesian_product_recursive(arrays, out=None):
    arrays = [numpy.asarray(x) for x in arrays]
    dtype = arrays[0].dtype

    n = numpy.prod([x.size for x in arrays])
    if out is None:
        out = numpy.zeros([n, len(arrays)], dtype=dtype)

    m = n // arrays[0].size
    out[:, 0] = numpy.repeat(arrays[0], m)
    if arrays[1:]:
        cartesian_product_recursive(arrays[1:], out=out[0:m, 1:])
        for j in range(1, arrays[0].size):
            out[j * m : (j + 1) * m, 1:] = out[0:m, 1:]
    return out


def cartesian_product_itertools(arrays):
    return numpy.array(list(itertools.product(*arrays)))


perfplot.show(
    setup=lambda n: 2 * (numpy.arange(n, dtype=float),),
    n_range=[2 ** k for k in range(13)],
    # setup=lambda n: 4 * (numpy.arange(n, dtype=float),),
    # n_range=[2 ** k for k in range(6)],
    kernels=[
        dstack_product,
        cartesian_product,
        cartesian_product_transpose,
        cartesian_product_recursive,
        cartesian_product_itertools,
    ],
    logx=True,
    logy=True,
    xlabel="len(a), len(b)",
    equality_check=None,
)

17

@ প্রেরকের অনুকরণীয় গ্রাউন্ড ওয়ার্কে বিল্ডিং আমি দুটি সংস্করণ নিয়ে এসেছি - একটি সি এর জন্য এবং একটি ফোর্টরান বিন্যাসের জন্য - যা প্রায়শই কিছুটা দ্রুত হয় faster

  • cartesian_product_transpose_ppহ'ল - @ প্রেরকের বিপরীতে cartesian_product_transposeযা সম্পূর্ণ আলাদা কৌশল ব্যবহার করে - এর একটি সংস্করণ cartesion_productআরও অনুকূল ট্রান্সপোজ মেমরি লেআউট + কিছু অতি সামান্য অপ্টিমাইজেশন ব্যবহার করে।
  • cartesian_product_ppমূল মেমরি লেআউট সঙ্গে লাঠি। যা এটি দ্রুত করে তোলে তা হ'ল এটি নিয়মিত অনুলিপি ব্যবহার করে। সংক্ষিপ্ত অনুলিপিগুলি এত দ্রুত গতিতে পরিণত হয়েছে যে কেবলমাত্র বৈধ ডেটা থাকা সত্ত্বেও এর একাংশের মধ্যে মেমরির একটি সম্পূর্ণ ব্লক অনুলিপি করা ভাল।

কিছু perfplots। আমি সি এবং ফোর্টরান লেআউটগুলির জন্য পৃথকগুলি তৈরি করেছি, কারণ এগুলি আলাদা আলাদা কাজ আইএমও।

'পিপি' এ শেষ হওয়া নামগুলি আমার পন্থাগুলি।

1) অনেক ক্ষুদ্র উপাদান (2 টি উপাদান প্রতিটি)

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

2) অনেক ছোট ছোট কারণ (4 টি উপাদান প্রতিটি)

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

3) সমান দৈর্ঘ্যের তিনটি কারণ

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

4) সমান দৈর্ঘ্যের দুটি কারণ

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

কোড (প্রতিটি প্লটের জন্য আলাদা রান করতে হবে খ / সি আমি কীভাবে পুনরায় সেট করতে হবে তা বুঝতে পারি না; এছাড়াও সম্পাদনা / মন্তব্য যথাযথভাবে / আউট করা প্রয়োজন):

import numpy
import numpy as np
from functools import reduce
import itertools
import timeit
import perfplot

def dstack_product(arrays):
    return numpy.dstack(
        numpy.meshgrid(*arrays, indexing='ij')
        ).reshape(-1, len(arrays))

def cartesian_product_transpose_pp(arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty((la, *map(len, arrays)), dtype=dtype)
    idx = slice(None), *itertools.repeat(None, la)
    for i, a in enumerate(arrays):
        arr[i, ...] = a[idx[:la-i]]
    return arr.reshape(la, -1).T

def cartesian_product(arrays):
    la = len(arrays)
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(numpy.ix_(*arrays)):
        arr[...,i] = a
    return arr.reshape(-1, la)

def cartesian_product_transpose(arrays):
    broadcastable = numpy.ix_(*arrays)
    broadcasted = numpy.broadcast_arrays(*broadcastable)
    rows, cols = numpy.prod(broadcasted[0].shape), len(broadcasted)
    dtype = numpy.result_type(*arrays)

    out = numpy.empty(rows * cols, dtype=dtype)
    start, end = 0, rows
    for a in broadcasted:
        out[start:end] = a.reshape(-1)
        start, end = end, end + rows
    return out.reshape(cols, rows).T

from itertools import accumulate, repeat, chain

def cartesian_product_pp(arrays, out=None):
    la = len(arrays)
    L = *map(len, arrays), la
    dtype = numpy.result_type(*arrays)
    arr = numpy.empty(L, dtype=dtype)
    arrs = *accumulate(chain((arr,), repeat(0, la-1)), np.ndarray.__getitem__),
    idx = slice(None), *itertools.repeat(None, la-1)
    for i in range(la-1, 0, -1):
        arrs[i][..., i] = arrays[i][idx[:la-i]]
        arrs[i-1][1:] = arrs[i]
    arr[..., 0] = arrays[0][idx]
    return arr.reshape(-1, la)

def cartesian_product_itertools(arrays):
    return numpy.array(list(itertools.product(*arrays)))


# from https://stackoverflow.com/a/1235363/577088
def cartesian_product_recursive(arrays, out=None):
    arrays = [numpy.asarray(x) for x in arrays]
    dtype = arrays[0].dtype

    n = numpy.prod([x.size for x in arrays])
    if out is None:
        out = numpy.zeros([n, len(arrays)], dtype=dtype)

    m = n // arrays[0].size
    out[:, 0] = numpy.repeat(arrays[0], m)
    if arrays[1:]:
        cartesian_product_recursive(arrays[1:], out=out[0:m, 1:])
        for j in range(1, arrays[0].size):
            out[j*m:(j+1)*m, 1:] = out[0:m, 1:]
    return out

### Test code ###
if False:
  perfplot.save('cp_4el_high.png',
    setup=lambda n: n*(numpy.arange(4, dtype=float),),
                n_range=list(range(6, 11)),
    kernels=[
        dstack_product,
        cartesian_product_recursive,
        cartesian_product,
#        cartesian_product_transpose,
        cartesian_product_pp,
#        cartesian_product_transpose_pp,
        ],
    logx=False,
    logy=True,
    xlabel='#factors',
    equality_check=None
    )
else:
  perfplot.save('cp_2f_T.png',
    setup=lambda n: 2*(numpy.arange(n, dtype=float),),
    n_range=[2**k for k in range(5, 11)],
    kernels=[
#        dstack_product,
#        cartesian_product_recursive,
#        cartesian_product,
        cartesian_product_transpose,
#        cartesian_product_pp,
        cartesian_product_transpose_pp,
        ],
    logx=True,
    logy=True,
    xlabel='length of each factor',
    equality_check=None
    )

এই দুর্দান্ত উত্তর ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ। যখন arraysকার্টেসিয়ান_প্রোডাক্ট_ট্রান্সপোজ_পি (অ্যারে) এর আকারটি একটি নির্দিষ্ট আকারকে ছাড়িয়ে যায়, তখন MemoryErrorঘটবে। এই পরিস্থিতিতে, আমি এই ফাংশনটি ফলাফলের আরও ছোট অংশ আনতে চাই। আমি এই বিষয়ে একটি প্রশ্ন পোস্ট করেছি । আপনি কি আমার প্রশ্নের সমাধান করতে পারেন? ধন্যবাদ।
সান বিয়ার

13

অক্টোবর ২০১ 2017 অনুসারে, নম্পির এখন একটি জেনেরিক np.stackফাংশন রয়েছে যা অক্ষ পরামিতি নেয়। এটি ব্যবহার করে, আমরা "ডিস্ট্যাক এবং জালগ্রিড" কৌশলটি ব্যবহার করে একটি "জেনারেটাইজড কার্টেসিয়ান পণ্য" পেতে পারি:

import numpy as np
def cartesian_product(*arrays):
    ndim = len(arrays)
    return np.stack(np.meshgrid(*arrays), axis=-1).reshape(-1, ndim)

axis=-1প্যারামিটারে নোট করুন । এটি ফলাফলের সর্বশেষ (অভ্যন্তরীণ-সর্বাধিক) অক্ষ। এটি ব্যবহারের সমতুল্য axis=ndim

অন্য একটি মন্তব্য, যেহেতু কার্টিজিয়ান পণ্য, খুব দ্রুত উড়িয়ে যদি না আমরা প্রয়োজন , কোনো কারণে মেমরি অ্যারের বুঝতে যদি পণ্য খুব বড়, আমরা ব্যবহার করতে চাইতে পারেন itertoolsএবং অন-ফ্লাই মান ব্যবহার।


8

আমি কিছুক্ষণের জন্য @ একনিটম উত্তরটি ব্যবহার করেছি , তবে টেনসরফ্লোতে যখন এটি করার চেষ্টা করছিলাম তবে আমি দেখতে পেলাম যে টেনসরফ্লো এর সমতুল্য নেই numpy.repeat()। কিছুটা পরীক্ষার পরে, আমি মনে করি পয়েন্টগুলির স্বেচ্ছাচারী ভেক্টরগুলির জন্য আমি আরও সাধারণ সমাধান খুঁজে পেয়েছি।

নালীর জন্য:

import numpy as np

def cartesian_product(*args: np.ndarray) -> np.ndarray:
    """
    Produce the cartesian product of arbitrary length vectors.

    Parameters
    ----------
    np.ndarray args
        vector of points of interest in each dimension

    Returns
    -------
    np.ndarray
        the cartesian product of size [m x n] wherein:
            m = prod([len(a) for a in args])
            n = len(args)
    """
    for i, a in enumerate(args):
        assert a.ndim == 1, "arg {:d} is not rank 1".format(i)
    return np.concatenate([np.reshape(xi, [-1, 1]) for xi in np.meshgrid(*args)], axis=1)

এবং টেনসরফ্লো এর জন্য:

import tensorflow as tf

def cartesian_product(*args: tf.Tensor) -> tf.Tensor:
    """
    Produce the cartesian product of arbitrary length vectors.

    Parameters
    ----------
    tf.Tensor args
        vector of points of interest in each dimension

    Returns
    -------
    tf.Tensor
        the cartesian product of size [m x n] wherein:
            m = prod([len(a) for a in args])
            n = len(args)
    """
    for i, a in enumerate(args):
        tf.assert_rank(a, 1, message="arg {:d} is not rank 1".format(i))
    return tf.concat([tf.reshape(xi, [-1, 1]) for xi in tf.meshgrid(*args)], axis=1)

6

Scikit-শিখতে প্যাকেজ ঠিক এই ফাস্ট বাস্তবায়ন রয়েছে:

from sklearn.utils.extmath import cartesian
product = cartesian((x,y))

নোট করুন যে আপনি যদি আউটপুট ক্রমের বিষয়ে চিন্তা করেন তবে এই প্রয়োগের কনভেনশনটি আপনি যা চান তার থেকে আলাদা। আপনার সঠিক অর্ডারিংয়ের জন্য, আপনি এটি করতে পারেন

product = cartesian((y,x))[:, ::-1]

এটি @ প্রেরকের ফাংশনের চেয়ে দ্রুত?
cs95

@ cᴏʟᴅsᴘᴇᴇᴅ আমি পরীক্ষা করিনি। আমি আশা করছিলাম যে এটি সি বা ফোর্টরান যেমন বাস্তবায়িত হয়েছিল এবং এইভাবে এটি বেশ অপরাজেয়, তবে এটি NumPy ব্যবহার করে লেখা হয়েছে বলে মনে হয়। এই হিসাবে, এই ফাংশনটি সুবিধাজনক তবে NumPy নিজেকে তৈরি করে যা তৈরি করতে পারে তার চেয়ে তাত্পর্যপূর্ণ দ্রুত হওয়া উচিত নয়।
jmd_dk

4

আরও সাধারণভাবে, যদি আপনার কাছে 2 ডি নিম্পের অ্যারে a এবং b থাকে এবং আপনি খ এর প্রতিটি সারিতে একটি করে প্রতিটি সারি একত্রিত করতে চান (সারিগুলির একটি কার্তেসিয়ান পণ্য, কোনও ডাটাবেজে যোগ দেওয়ার মতো ধরণের), আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন :

import numpy
def join_2d(a, b):
    assert a.dtype == b.dtype
    a_part = numpy.tile(a, (len(b), 1))
    b_part = numpy.repeat(b, len(a), axis=0)
    return numpy.hstack((a_part, b_part))

3

ম্যাপের ফাংশনটির সাথে জেনারেটর এক্সপ্রেশনকে একত্রিত করে আপনি যেটি দ্রুত পেতে পারেন তা হ'ল:

import numpy
import datetime
a = np.arange(1000)
b = np.arange(200)

start = datetime.datetime.now()

foo = (item for sublist in [list(map(lambda x: (x,i),a)) for i in b] for item in sublist)

print (list(foo))

print ('execution time: {} s'.format((datetime.datetime.now() - start).total_seconds()))

আউটপুট (আসলে পুরো ফলাফলের তালিকা মুদ্রিত):

[(0, 0), (1, 0), ...,(998, 199), (999, 199)]
execution time: 1.253567 s

বা একটি ডাবল জেনারেটর এক্সপ্রেশন ব্যবহার করে:

a = np.arange(1000)
b = np.arange(200)

start = datetime.datetime.now()

foo = ((x,y) for x in a for y in b)

print (list(foo))

print ('execution time: {} s'.format((datetime.datetime.now() - start).total_seconds()))

আউটপুট (পুরো তালিকা মুদ্রিত):

[(0, 0), (1, 0), ...,(998, 199), (999, 199)]
execution time: 1.187415 s

অ্যাকাউন্টে বিবেচনা করুন যে গণনার বেশিরভাগ সময় মুদ্রণ কমান্ডে যায়। জেনারেটরের গণনা অন্যথায় শালীনভাবে দক্ষ। প্রিন্ট না করে গণনার সময়গুলি হ'ল:

execution time: 0.079208 s

জেনারেটর এক্সপ্রেশন + মানচিত্র ফাংশন এবং এর জন্য:

execution time: 0.007093 s

দ্বিগুণ জেনারেটর এক্সপ্রেশন জন্য।

আপনি যা চান তা যদি স্থায়ী জোড়গুলির প্রত্যেকটির প্রকৃত পণ্য গণনা করা হয় তবে এটিকে নপি ম্যাট্রিক্স পণ্য হিসাবে সমাধান করা সবচেয়ে দ্রুত:

a = np.arange(1000)
b = np.arange(200)

start = datetime.datetime.now()

foo = np.dot(np.asmatrix([[i,0] for i in a]), np.asmatrix([[i,0] for i in b]).T)

print (foo)

print ('execution time: {} s'.format((datetime.datetime.now() - start).total_seconds()))

আউটপুট:

 [[     0      0      0 ...,      0      0      0]
 [     0      1      2 ...,    197    198    199]
 [     0      2      4 ...,    394    396    398]
 ..., 
 [     0    997   1994 ..., 196409 197406 198403]
 [     0    998   1996 ..., 196606 197604 198602]
 [     0    999   1998 ..., 196803 197802 198801]]
execution time: 0.003869 s

এবং মুদ্রণ ছাড়াই (এক্ষেত্রে ম্যাট্রিক্সের একটি ক্ষুদ্র অংশটি প্রকৃতপক্ষে মুদ্রিত হওয়ার কারণে এটি খুব বেশি সাশ্রয় করে না):

execution time: 0.003083 s

পণ্য গণনার জন্য, বাইরের পণ্য সম্প্রচার foo = a[:,None]*bদ্রুত হয়। আপনার সময় পদ্ধতিটি ছাড়াই ব্যবহার করা print(foo), এটি 0.001103 s বনাম 0.002225 এস। টাইমিট ব্যবহার করে এটি 304 ডিগ্রি বনাম 1.6 এমএস। ম্যাট্রিক্স নাদারের চেয়ে ধীর হিসাবে পরিচিত, তাই আমি আপনার কোডটি এনপি.আরয়ের সাহায্যে চেষ্টা করেছিলাম তবে এটি সম্প্রচারের তুলনায় এখনও ধীর (1.57 এমএস)।
syockit

2

এটি সহজেই itertools.product পদ্ধতি ব্যবহার করে করা যেতে পারে

from itertools import product
import numpy as np

x = np.array([1, 2, 3])
y = np.array([4, 5])
cart_prod = np.array(list(product(*[x, y])),dtype='int32')

ফলাফল: অ্যারে ([
[1, 4],
[1, 5],
[2, 4],
[2, 5],
[3, 4],
[3, 5]], টাইপ = ইন্ট 32)

সম্পাদনের সময়: 0.000155 এস


1
আপনাকে নিম্প কল করার দরকার নেই। সরল পুরাতন পাইথন অ্যারে এটির সাথেও কাজ করে।
কোডি

0

যে নির্দিষ্ট ক্ষেত্রে আপনার প্রতিটি জুটির সংযোজন সম্পর্কিত সাধারণ ক্রিয়াকলাপ করা দরকার, আপনি একটি অতিরিক্ত মাত্রা প্রবর্তন করতে এবং সম্প্রচারকে কাজটি করতে দিতে পারেন:

>>> a, b = np.array([1,2,3]), np.array([10,20,30])
>>> a[None,:] + b[:,None]
array([[11, 12, 13],
       [21, 22, 23],
       [31, 32, 33]])

আমি নিশ্চিত নই যে আসলে জোড়াটি নিজের কাছে পাওয়ার কোনও অনুরূপ উপায় আছে কিনা।


যদি আপনি dtypeতা floatকরতে পারেন (a[:, None, None] + 1j * b[None, :, None]).view(float)যা আশ্চর্যজনকভাবে দ্রুত।
পল পাঞ্জার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.