Takip koduna sahibim:
r = numpy.zeros(shape = (width, height, 9))
width x height x 9
Sıfırlarla dolu bir matris oluşturur . Bunun yerine, NaN
kolay bir şekilde s yerine onları başlatmak için bir işlev veya yol olup olmadığını bilmek istiyorum .
Takip koduna sahibim:
r = numpy.zeros(shape = (width, height, 9))
width x height x 9
Sıfırlarla dolu bir matris oluşturur . Bunun yerine, NaN
kolay bir şekilde s yerine onları başlatmak için bir işlev veya yol olup olmadığını bilmek istiyorum .
Yanıtlar:
Nadiren numpy vektör işlemleri için döngüler gerekir. Başlatılmamış bir dizi oluşturabilir ve tüm girişlere aynı anda atayabilirsiniz:
>>> a = numpy.empty((3,3,))
>>> a[:] = numpy.nan
>>> a
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
Alternatifleri a[:] = numpy.nan
burada ve a.fill(numpy.nan)
Blaenk'in gönderdiği gibi zamanladım :
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)"
10000 loops, best of 3: 54.3 usec per loop
$ python -mtimeit "import numpy as np; a = np.empty((100,100));" "a[:] = np.nan"
10000 loops, best of 3: 88.8 usec per loop
Zamanlamalar ndarray.fill(..)
daha hızlı bir alternatif olarak bir tercih göstermektedir . OTOH, numpy'nin o zaman bütün dilimlere değerler atayabileceğiniz kolaylık uygulamasını seviyorum, kodun niyeti çok açık.
Not ndarray.fill
yerinde onun işlemini gerçekleştiren, bu yüzden numpy.empty((3,3,)).fill(numpy.nan)
onun yerine dönecektir None
.
a = numpy.empty((3, 3,)) * numpy.nan
. fill
Atama yönteminden daha hızlı ama daha yavaş zamanladı , ancak bir oneliner !!
.fill()
Yöntemi tercih ederim , ancak diziler büyüdükçe hızlardaki fark pratik olarak hiçbir şeye düşmez.
np.empty([2, 5])
bir dizi oluşturur, ardından fill()
o diziyi yerinde değiştirir, ancak bir kopya veya başvuru döndürmez. np.empty(2, 5)
Bir ada göre aramak istiyorsanız ("atama değişkendir"), yerinde işlemler yapmadan önce bunu yapmanız gerekir. Yaparsanız aynı tür şeyler olur [1, 2, 3].insert(1, 4)
. Liste oluşturulur ve 4 eklenir, ancak listeye referans almak imkansızdır (ve bu nedenle çöp toplandığı varsayılabilir). Dizeler gibi değişmez verilerde, yerinde çalışamayacağınız için bir kopya döndürülür. Pandalar her ikisini de yapabilir.
Başka bir seçenek kullanmaktır numpy.full
, NumPy 1.8+
a = np.full([height, width, 9], np.nan)
Bu oldukça esnektir ve istediğiniz başka bir numarayla doldurabilirsiniz.
full
. np.empy((x,y))*np.nan
iyi bir ikincilik (ve numpy'nin eski sürümleri için uyumluluk).
fill
python -mtimeit "import numpy as np; a = np.empty((100,100));" "a.fill(np.nan)" 100000 loops, best of 3: 13.3 usec per loop python -mtimeit "import numpy as np; a = np.full((100,100), np.nan);" 100000 loops, best of 3: 18.5 usec per loop
python -mtimeit "import numpy as np; a = np.empty((1000,1000)); a.fill(np.nan)" 1000 loops, best of 3: 381 usec per loop $ python -mtimeit "import numpy as np; a = np.full((1000,1000), np.nan);" 1000 loops, best of 3: 383 usec per loop
Yeterince büyük vektörler / matrisler doldurmak için ben hız için önerilen alternatifler karşılaştırmış ve tespit, tüm hariç alternatifleri val * ones
ve array(n * [val])
eşit hızlı.
Grafiği yeniden oluşturmak için kod:
import numpy
import perfplot
val = 42.0
def fill(n):
a = numpy.empty(n)
a.fill(val)
return a
def colon(n):
a = numpy.empty(n)
a[:] = val
return a
def full(n):
return numpy.full(n, val)
def ones_times(n):
return val * numpy.ones(n)
def list(n):
return numpy.array(n * [val])
perfplot.show(
setup=lambda n: n,
kernels=[fill, colon, full, ones_times, list],
n_range=[2 ** k for k in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
)
numpy.full(n, val)
daha yavaşa = numpy.empty(n) .. a.fill(val)
Aşina mısın numpy.nan
?
Aşağıdaki gibi kendi yönteminizi oluşturabilirsiniz:
def nans(shape, dtype=float):
a = numpy.empty(shape, dtype)
a.fill(numpy.nan)
return a
Sonra
nans([3,4])
çıktı
array([[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN],
[ NaN, NaN, NaN, NaN]])
Bu kodu bir posta listesi iş parçacığında buldum .
.empty
Veya .full
yöntemlerini hemen hatırlamazsanız, çarpma işlemini her zaman kullanabilirsiniz :
>>> np.nan * np.ones(shape=(3,2))
array([[ nan, nan],
[ nan, nan],
[ nan, nan]])
Tabii ki başka herhangi bir sayısal değerle de çalışır:
>>> 42 * np.ones(shape=(3,2))
array([[ 42, 42],
[ 42, 42],
[ 42, 42]])
Ancak @ u0b34a0f6ae'nin kabul edilen cevabı 3 kat daha hızlıdır (CPU döngüleri, numpy sözdizimini hatırlamak için beyin döngüleri değil;):
$ python -mtimeit "import numpy as np; X = np.empty((100,100));" "X[:] = np.nan;"
100000 loops, best of 3: 8.9 usec per loop
(predict)laneh@predict:~/src/predict/predict/webapp$ master
$ python -mtimeit "import numpy as np; X = np.ones((100,100));" "X *= np.nan;"
10000 loops, best of 3: 24.9 usec per loop
Başka bir alternatif numpy.broadcast_to(val,n)
boyuttan bağımsız olarak sabit sürede dönen ve aynı zamanda en fazla bellek verimli olanıdır (tekrarlanan elemanın bir görünümünü döndürür). Uyarı, döndürülen değerin salt okunur olmasıdır.
Aşağıda, Nico Schlömer'in cevabı ile aynı kriter kullanılarak önerilen diğer tüm yöntemlerin performanslarının bir karşılaştırması verilmiştir .
Söylendiği gibi, numpy.empty () yoludur. Ancak nesneler için, fill () işlevi tam olarak ne düşündüğünü yapamayabilir:
In[36]: a = numpy.empty(5,dtype=object)
In[37]: a.fill([])
In[38]: a
Out[38]: array([[], [], [], [], []], dtype=object)
In[39]: a[0].append(4)
In[40]: a
Out[40]: array([[4], [4], [4], [4], [4]], dtype=object)
Bunun bir yolu örneğin:
In[41]: a = numpy.empty(5,dtype=object)
In[42]: a[:]= [ [] for x in range(5)]
In[43]: a[0].append(4)
In[44]: a
Out[44]: array([[4], [], [], [], []], dtype=object)
Burada henüz bahsedilmeyen bir başka olasılık da NumPy döşemesini kullanmaktır:
a = numpy.tile(numpy.nan, (3, 3))
Ayrıca verir
array([[ NaN, NaN, NaN],
[ NaN, NaN, NaN],
[ NaN, NaN, NaN]])
Hız karşılaştırmasını bilmiyorum.
np.nan
int'ye dönüştürüldüğünde yanlış gidiyor.