uyuşmuş bir dizi başlatmak


130

Uyuşmuş bir şekil dizisini başlatmanın ve ona eklemenin bir yolu var mı? Neye ihtiyacım olduğunu bir liste örneği ile açıklayacağım. Bir döngüde oluşturulan nesnelerin bir listesini oluşturmak istersem şunları yapabilirim:

a = []
for i in range(5):
    a.append(i)

Uyuşuk bir dizi ile benzer bir şey yapmak istiyorum. Vstack, concatenate vb. Hakkında bilgim var. Ancak, görünüşe göre bunlar girdi olarak iki numpy dizi gerektiriyor. İhtiyacım olan şey:

big_array # Initially empty. This is where I don't know what to specify
for i in range(5):
    array i of shape = (2,4) created.
    add to big_array

big_arrayBir şekle sahip olmalıdır (10,4). Bu nasıl yapılır?


DÜZENLE:

Aşağıdaki açıklamayı eklemek istiyorum. Tanımlayıp big_array = numpy.zeros((10,4))sonra doldurabileceğimin farkındayım . Ancak bu, big_array boyutunu önceden belirtmeyi gerektirir. Bu durumda boyutu biliyorum, ama ya bilmiyorsam? .appendListeyi python'da genişletmek için işlevi kullandığımızda, son boyutunu önceden bilmemize gerek yoktur. Boş bir diziden başlayarak daha küçük dizilerden daha büyük bir dizi oluşturmak için benzer bir şey olup olmadığını merak ediyorum.


Bu arada ilk kod örneği, bir liste anlama şeklinde düzgün ve özlü yazılabilir: [i for i in range(5)]. ( list(range(5))
Aynı şekilde

sizin için hangi çözüm işe yaradı? x = numpy.array()tıpkı bir listeye yaptığımız gibi benzer bir şey yapmaya çalışıyorum y = []; ama işe yaramadı
kRazzy R

Yanıtlar:


160

numpy.zeros

Sıfırlarla dolu, verilen şekil ve türde yeni bir dizi döndürür.

veya

numpy.ones

Verilen şekil ve türde yeni bir dizi döndür, bunlarla dolu.

veya

numpy.empty

Girişleri başlatmadan, verilen şekil ve türde yeni bir dizi döndürür.


Bununla birlikte, bir listeye öğeler ekleyerek bir dizi oluşturduğumuz zihniyet, numpy'de pek kullanılmaz, çünkü daha az etkilidir (numpy veri türleri, temeldeki C dizilerine çok daha yakındır). Bunun yerine, diziyi olması gereken boyuta önceden tahsis etmeli ve ardından satırları doldurmalısınız. numpy.appendGerekirse kullanabilirsiniz .


2
Big_array = numpy.zeros ayarlayabileceğimi ve sonra onu oluşturulan küçük dizilerle doldurabileceğimi biliyorum. Ancak bu, önceden big_array boyutunu belirlememi gerektiriyor. Önceden boyutu belirtmediğim liste işlevinin .append gibi bir şey yok mu? Teşekkürler!
Curious2learn

2
@ Curious2learn. Hayır, Numpy'de eklemek gibisi yoktur. Dizileri birleştiren veya yeni diziler oluşturarak onları istifleyen işlevler vardır, ancak bunu ekleyerek yapmazlar. Bunun nedeni, veri yapılarının kurulma biçimidir. Numpy dizileri, değerleri daha kompakt bir şekilde depolayabildikleri için hızlı yapılır, ancak bu hızı elde etmek için sabit boyuta sahip olmaları gerekir. Python listeleri hız ve boyut pahasına daha esnek olacak şekilde tasarlanmıştır.
Justin Peel

3
@ Meraklı: iyi, bir uyuşukluk var append. Sadece önceden tahsis etmemek daha az etkilidir (bu durumda, appendher seferinde tüm diziyi kopyaladığı için çok daha az verimli ), bu yüzden standart bir teknik değildir.
Katriel

1
Ya np.emptydizinin sadece bir kısmı değerlerle doldurulursa? Kalan "boş" öğeler ne olacak?
Lee

1
Yalnızca genişliğini (örn için gerekli biliyorum biliyorum varsa np.concatenate()) kullanarak, ile başlatabilir: np.empty((0, some_width)). 0, yani ilk diziniz çöp olmayacak.
NumesSanguis

40

Bunu genellikle benim yaptığım yol, normal bir liste oluşturup, ardından öğelerimi buna eklemek ve son olarak listeyi aşağıdaki gibi bir diziye dönüştürmektir:

import numpy as np
big_array = [] #  empty regular list
for i in range(5):
    arr = i*np.ones((2,4)) # for instance
    big_array.append(arr)
big_np_array = np.array(big_array)  # transformed to a numpy array

Tabii ki, son nesneniz oluşturma aşamasında bellekte iki kat daha fazla yer kaplar, ancak python listesine eklemek çok hızlıdır ve ayrıca np.array () kullanarak oluşturma.


11
Dizinin boyutunu önceden biliyorsanız, bu yol değildir , ancak ... Dizinin ne kadar büyük olacağını bilmediğimde bu yöntemi sık sık kullanıyorum. Örneğin, bir dosyadan veya başka bir işlemden veri okurken. Python ve numpy oldukça zeki olduğundan, ilk bakışta göründüğü kadar berbat değil.
travc

18

Numpy 1.8'de sunulanlar:

numpy.full

Fill_value ile doldurulmuş yeni bir şekil ve tip dizisi döndürür.

Örnekler:

>>> import numpy as np
>>> np.full((2, 2), np.inf)
array([[ inf,  inf],
       [ inf,  inf]])
>>> np.full((2, 2), 10)
array([[10, 10],
       [10, 10]])

13

Python'lar için dizi analoğu

a = []
for i in range(5):
    a.append(i)

dır-dir:

import numpy as np

a = np.empty((0))
for i in range(5):
    a = np.append(a, i)

5
@NicholasTJ: uyuşmuş empty((0))bir diziyi başlatır.
Adobe

2
np.empty ((0)) içindeki parantezler gereksizdir.
Szymon Roziewski

7

numpy.fromiter() aradığınız şey:

big_array = numpy.fromiter(xrange(5), dtype="int")

Aynı zamanda oluşturucu ifadelerle de çalışır, örneğin:

big_array = numpy.fromiter( (i*(i+1)/2 for i in xrange(5)), dtype="int" )

Dizinin uzunluğunu önceden biliyorsanız, isteğe bağlı bir 'sayım' bağımsız değişkeniyle belirtebilirsiniz.


2
Aslında timeit'i çalıştırdım ve bence np.fromiter () np.array () 'den daha yavaş olabilir. timeit ("np.array (xrange (100) 'de i için)", setup = "numpy olarak np olarak içe aktar", sayı = 10000) -> 0.02539992332458496, versus timeit ("np.fromiter ((xrange ( 100)), dtype = int) ", setup =" numpy'i np olarak içe aktar ", sayı = 10000) -> 0.13351011276245117
hlin117

6

Dizi hesaplama yaparken açık döngülerden olabildiğince kaçınmak istersiniz, çünkü bu, bu tür bilgi işlemden elde edilen hız kazancını azaltır. Uyuşmuş bir diziyi başlatmanın birçok yolu vardır. Sıfırlarla doldurulmasını istiyorsanız, katrielalex'in dediği gibi yapın:

big_array = numpy.zeros((10,4))

EDIT: Ne tür bir sıralama yapıyorsunuz? Diziler oluşturan farklı numpy işlevlerini kontrol etmelisiniz, örneğin numpy.linspace(start, stop, size)(eşit aralıklı sayı), veya numpy.arange(start, stop, inc). Mümkün olduğunda, bu işlevler dizileri aynı işi açık döngülerde yapmaktan önemli ölçüde daha hızlı hale getirecektir.


6

Uyuşmuş bir diziyi belirli bir matrisle başlatmak için:

import numpy as np

mat = np.array([[1, 1, 0, 0, 0],
                [0, 1, 0, 0, 1],
                [1, 0, 0, 1, 1],
                [0, 0, 0, 0, 0],
                [1, 0, 1, 0, 1]])

print mat.shape
print mat

çıktı:

(5, 5)
[[1 1 0 0 0]
 [0 1 0 0 1]
 [1 0 0 1 1]
 [0 0 0 0 0]
 [1 0 1 0 1]]

5

İlk dizi örneğiniz için,

a = numpy.arange(5)

Big_array'i başlatmak için kullanın

big_array = numpy.zeros((10,4))

Bu, oldukça tipik olan sıfırlarla başlatmak istediğinizi varsayar, ancak bir diziyi numpy ile başlatmanın birçok başka yolu vardır .

Düzenleme: Big_array'in boyutunu önceden bilmiyorsanız, genellikle en iyisi append'i kullanarak bir Python listesi oluşturmaktır ve listede her şeyi topladığınızda, bu listeyi numpy.array(mylist). Bunun nedeni, listelerin çok verimli ve hızlı bir şekilde büyümesi anlamına gelirken, numpy.concatenate çok verimsiz olacaktır çünkü numpy dizileri kolayca boyut değiştirmez. Ancak her şey bir listede toplandığında ve son dizi boyutunu öğrendikten sonra, uyuşmuş bir dizi verimli bir şekilde oluşturulabilir.


3

Önce şekli tanımlamayı öneririm. Ardından değerleri eklemek için üzerinde yineleyin.

big_array= np.zeros(shape = ( 6, 2 ))
for it in range(6):
    big_array[it] = (it,it) # For example

>>>big_array

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

3

Aşağıdaki durumda olduğunuzda:

a = []
for i in range(5):
    a.append(i)

ve uyuşuk olarak benzer bir şey istiyorsanız, önceki birkaç cevap bunu yapmanın yollarını işaret etti, ancak @katrielalex'in belirttiği gibi bu yöntemlerin verimli olmadığını söylediler. Bunu yapmanın etkili yolu, uzun bir liste oluşturmak ve ardından uzun bir listeniz olduktan sonra istediğiniz şekilde yeniden şekillendirmektir. Örneğin, bir dosyadan bazı satırları okuyorum ve her satırda bir sayı listesi var ve uyuşmuş bir şekil dizisi oluşturmak istiyorum (okunan satır sayısı, her satırdaki vektörün uzunluğu). İşte bunu nasıl daha verimli yapacağım:

long_list = []
counter = 0
with open('filename', 'r') as f:
    for row in f:
        row_list = row.split()
        long_list.extend(row_list)
        counter++
#  now we have a long list and we are ready to reshape
result = np.array(long_list).reshape(counter, len(row_list)) #  desired numpy array

2

Bunun biraz geç olduğunun farkındayım, ancak boş diziye indekslemeden bahseden diğer cevaplardan hiçbirini fark etmedim:

big_array = numpy.empty(10, 4)
for i in range(5):
    array_i = numpy.random.random(2, 4)
    big_array[2 * i:2 * (i + 1), :] = array_i

Bu şekilde, tüm sonuç dizisini önceden tahsis edersiniz numpy.emptyve dizine alınmış atamayı kullanarak satırları doldurursunuz.

Verdiğiniz örnek emptyyerine önceden tahsis etmek tamamen güvenlidir zeros, çünkü tüm dizinin ürettiğiniz parçalarla doldurulacağını garanti ediyorsunuz.


2

Belki böyle bir şey ihtiyaçlarınıza uyacaktır ..

import numpy as np

N = 5
res = []

for i in range(N):
    res.append(np.cumsum(np.ones(shape=(2,4))))

res = np.array(res).reshape((10, 4))
print(res)

Aşağıdaki çıktıyı üreten

[[ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]
 [ 1.  2.  3.  4.]
 [ 5.  6.  7.  8.]]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.