"ক্লোনিং" সারি বা কলামের ভেক্টর


154

কখনও কখনও কোনও ম্যাট্রিক্সে একটি সারি বা কলাম ভেক্টর "ক্লোন করতে" দরকারী। ক্লোনিংয়ের অর্থ আমি একটি সারি ভেক্টরকে যেমন রূপান্তরিত করি

[1,2,3]

ম্যাট্রিক্সে

[[1,2,3]
 [1,2,3]
 [1,2,3]
]

বা কলামের ভেক্টর যেমন

[1
 2
 3
]

মধ্যে

[[1,1,1]
 [2,2,2]
 [3,3,3]
]

মাতলাব বা অষ্টভরে এটি খুব সহজেই সম্পন্ন করা হয়:

 x = [1,2,3]
 a = ones(3,1) * x
 a =

    1   2   3
    1   2   3
    1   2   3

 b = (x') * ones(1,3)
 b =

    1   1   1
    2   2   2
    3   3   3

আমি এটাকে অদ্ভুতভাবে পুনরাবৃত্তি করতে চাই, তবে ব্যর্থ

In [14]: x = array([1,2,3])
In [14]: ones((3,1)) * x
Out[14]:
array([[ 1.,  2.,  3.],
       [ 1.,  2.,  3.],
       [ 1.,  2.,  3.]])
# so far so good
In [16]: x.transpose() * ones((1,3))
Out[16]: array([[ 1.,  2.,  3.]])
# DAMN
# I end up with 
In [17]: (ones((3,1)) * x).transpose()
Out[17]:
array([[ 1.,  1.,  1.],
       [ 2.,  2.,  2.],
       [ 3.,  3.,  3.]])

প্রথম পদ্ধতি ( In [16]) কেন কাজ করছিল না ? অজগর থেকে আরও মার্জিত উপায়ে এই কাজটি অর্জন করার কোনও উপায় আছে কি?


6
মতলব-এ, দ্রষ্টব্য যে এটি ব্যবহার করা আরও দ্রুত repmat: repmat([1 2 3],3,1)বাrepmat([1 2 3].',1,3)
লুইস মেন্ডো

অক্টোটাও আছে repmat
ma11 she28

যারা পান্ডাস ডাটাফ্রেমের সাথে একই কাজ করতে চাইছেন তারা tile_df এখানে
zelusp

উত্তর:


80

এটি করার জন্য এখানে একটি মার্জিত, পাইথোনিক উপায়:

>>> array([[1,2,3],]*3)
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

>>> array([[1,2,3],]*3).transpose()
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

সমস্যাটি [16]মনে হয় ট্রান্সপোজোর একটি অ্যারের জন্য কোনও প্রভাব নেই। আপনি সম্ভবত পরিবর্তে একটি ম্যাট্রিক্স চাই:

>>> x = array([1,2,3])
>>> x
array([1, 2, 3])
>>> x.transpose()
array([1, 2, 3])
>>> matrix([1,2,3])
matrix([[1, 2, 3]])
>>> matrix([1,2,3]).transpose()
matrix([[1],
        [2],
        [3]])

1
(TRANSPOSE, অথবা যখন একটি পরিণত উদাহরণে বর্গ এক জন্য 2D অ্যারে জন্য কাজ করে, যেমন (N,1)-shape অ্যারে ব্যবহার .reshape(-1, 1))
মার্ক

34
এটি অত্যন্ত অদক্ষ। Pv. এর উত্তরেnumpy.tile প্রদর্শিত হিসাবে ব্যবহার করুন ।
ডেভিড হেফারনান

302

ব্যবহার numpy.tile:

>>> tile(array([1,2,3]), (3, 1))
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

বা পুনরাবৃত্তি কলামগুলির জন্য:

>>> tile(array([[1,2,3]]).transpose(), (1, 3))
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

16
ভোট দিন! আমার সিস্টেমে, 10000 উপাদান সহ একটি ভেক্টরের জন্য 1000 বার পুনরাবৃত্তি করা হয়েছে, tileবর্তমানে গৃহীত উত্তরের (গুণক-অপারেটর-পদ্ধতি ব্যবহার করে) পদ্ধতির চেয়ে পদ্ধতিটি 19.5 গুণ বেশি দ্রুত।
ডাঃ জানু-ফিলিপ গেহর্কেকে

1
দ্বিতীয় বিভাগে ("কলামগুলি পুনরাবৃত্তি করছে"), আপনি স্কোয়ার ব্র্যাকেটের দ্বিতীয় সেটটি কী করেন তা ব্যাখ্যা করতে পারেন, [[1,2,3]]
পিঁপড়া

@ এবং এটি প্রথম অক্ষের 1 (আপনার স্ক্রিনের উল্লম্ব) এবং 2 অক্ষের দৈর্ঘ্য 3 (আপনার স্ক্রিনের অনুভূমিক) দিয়ে 2 ডি অ্যারে তৈরি করে D এর পরে ট্রান্সপোসিংয়ের এটি প্রথম অক্ষের দৈর্ঘ্য 3 এবং দ্বিতীয় অক্ষের দৈর্ঘ্য 1 করে have (1, 3)এই কলামটি তিনবারের মধ্যে একটি টাইলের আকারের অনুলিপি করা হয়, এ কারণেই ফলাফলের সারিগুলিতে প্রতিটি আলাদা আলাদা উপাদান থাকে।
বলপয়েন্টবেন

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

আমি এটি 2 ডি 3 ডি সমাধানের জন্য কাজ করতে পারি না :(
জন কোটজিক

41

প্রথম নোট করুন যে নম্পির সম্প্রচারিত ক্রিয়াকলাপগুলির সাথে সাধারণত সারি এবং কলামগুলি নকল করা প্রয়োজন হয় না। বর্ণনার জন্য এটি এবং এটি দেখুন ।

তবে এটি করার জন্য, পুনরাবৃত্তি এবং নিউাক্সিস সম্ভবত সেরা উপায়

In [12]: x = array([1,2,3])

In [13]: repeat(x[:,newaxis], 3, 1)
Out[13]: 
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

In [14]: repeat(x[newaxis,:], 3, 0)
Out[14]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

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

In [15]: x = array([[1, 2, 3]])  # note the double brackets

In [16]: (ones((3,1))*x).transpose()
Out[16]: 
array([[ 1.,  1.,  1.],
       [ 2.,  2.,  2.],
       [ 3.,  3.,  3.]])

5
নিউ্যাক্সিসের অতিরিক্ত সুবিধা রয়েছে যা এটি প্রয়োজন পর্যন্ত ডেটা অনুলিপি করে না। সুতরাং আপনি যদি এটি আরও 3x3 অ্যারেকে গুণিত করতে বা যোগ করার জন্য করছেন তবে পুনরাবৃত্তিটি অপ্রয়োজনীয়। ধারণাটি পেতে অদ্ভুত সম্প্রচারে পড়ুন।
আফোগলিয়া

@ এফোগলিয়া - ভাল কথা আমি এটিকে নির্দেশ করতে আমার উত্তর আপডেট করেছি।
tom10

1
np.repeatবনাম ব্যবহার করে কী লাভ np.tile?
mrgloom

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

12

দিন:

>>> n = 1000
>>> x = np.arange(n)
>>> reps = 10000

জিরো-ব্যয় বরাদ্দ

একটি ভিউ কোনও অতিরিক্ত মেমরি নেয় না। সুতরাং, এই ঘোষণাগুলি তাত্ক্ষণিক:

# New axis
x[np.newaxis, ...]

# Broadcast to specific shape
np.broadcast_to(x, (reps, n))

জোর করে বরাদ্দ

আপনি যদি বিষয়বস্তুগুলিকে মেমরির মধ্যে থাকতে বাধ্য করেন তবে:

>>> %timeit np.array(np.broadcast_to(x, (reps, n)))
10.2 ms ± 62.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> %timeit np.repeat(x[np.newaxis, :], reps, axis=0)
9.88 ms ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> %timeit np.tile(x, (reps, 1))
9.97 ms ± 77.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

তিনটি পদ্ধতিই প্রায় একই গতি।

গুনতি

>>> a = np.arange(reps * n).reshape(reps, n)
>>> x_tiled = np.tile(x, (reps, 1))

>>> %timeit np.broadcast_to(x, (reps, n)) * a
17.1 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> %timeit x[np.newaxis, :] * a
17.5 ms ± 300 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

>>> %timeit x_tiled * a
17.6 ms ± 240 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

তিনটি পদ্ধতিই প্রায় একই গতি।


উপসংহার

আপনি যদি কোনও গণনার পূর্বে প্রতিলিপি করতে চান তবে "শূন্য-ব্যয় বরাদ্দ" পদ্ধতির একটি ব্যবহার করে বিবেচনা করুন। আপনি "জোরপূর্বক বরাদ্দ" এর কার্যকারিতা জরিমানা ভোগ করবেন না।


8

আমি মনে করি ব্রত সম্প্রচারটি নিম্পিতে ব্যবহার করা সবচেয়ে ভাল এবং দ্রুত

আমি নিম্নলিখিত হিসাবে একটি তুলনা করেছি

import numpy as np
b = np.random.randn(1000)
In [105]: %timeit c = np.tile(b[:, newaxis], (1,100))
1000 loops, best of 3: 354 µs per loop

In [106]: %timeit c = np.repeat(b[:, newaxis], 100, axis=1)
1000 loops, best of 3: 347 µs per loop

In [107]: %timeit c = np.array([b,]*100).transpose()
100 loops, best of 3: 5.56 ms per loop

ব্রডকাস্ট ব্যবহার করে প্রায় 15 গুণ দ্রুত


আপনি Noneএকই জিনিস করতে সূচক করতে পারেন ।
ড্যানিয়েলস্যাঙ্ক

নিউএক্সিস কি ?!
dreab

np.newaxis কোনওটিরই একটি নাম নেই
জন কেটেজিক

পুনরাবৃত্তিটি দ্রুত ছিল: 5.56 এমএস = 5560
অগস্টো ফ্যাডেল

4

একটি পরিষ্কার সমাধান হ'ল নিম্পের বাইরের-পণ্য ফাংশনটি কোনও ভেক্টরের সাথে ব্যবহার করা:

np.outer(np.ones(n), x)

nপুনরাবৃত্তি সারি দেয় । পুনরাবৃত্তি কলামগুলি পেতে আর্গুমেন্টের আদেশটি স্যুইচ করুন। সমান সংখ্যক সারি এবং কলাম পেতে পেতে পারে

np.outer(np.ones_like(x), x)

3

তুমি ব্যবহার করতে পার

np.tile(x,3).reshape((4,3))

টাইল ভেক্টরের রেপগুলি তৈরি করবে

এবং পুনর্নির্মাণ এটি আপনার পছন্দ মতো আকার দেবে


1

যদি আপনার কাছে পান্ডাস ডেটাফ্রেম থাকে এবং আপনি টাইপগুলি এমনকি শ্রেণিবদ্ধগুলিকে সংরক্ষণ করতে চান তবে এটি করার একটি দ্রুত উপায়:

import numpy as np
import pandas as pd
df = pd.DataFrame({1: [1, 2, 3], 2: [4, 5, 6]})
number_repeats = 50
new_df = df.reindex(np.tile(df.index, number_repeats))

-1
import numpy as np
x=np.array([1,2,3])
y=np.multiply(np.ones((len(x),len(x))),x).T
print(y)

উৎপাদনের:

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