Uyuşuk bir dizideki negatif değerleri değiştirin


91

Bir dizideki tüm negatif değerleri 0 ile değiştirmenin basit bir yolu var mı?

Bir NumPy dizisi kullanarak nasıl yapılacağına dair tam bir blok yaşıyorum.

Örneğin

a = array([1, 2, 3, -4, 5])

Dönmem gerek

[1, 2, 3, 0, 5]

a < 0 verir:

[False, False, False, True, False]

Burada sıkıştığım yer burası - bu diziyi orijinal diziyi değiştirmek için nasıl kullanacağım.

Yanıtlar:


139

Yolun yarısındasın. Deneyin:

In [4]: a[a < 0] = 0

In [5]: a
Out[5]: array([1, 2, 3, 0, 5])

90

Deneyin numpy.clip:

>>> import numpy
>>> a = numpy.arange(-10, 10)
>>> a
array([-10,  -9,  -8,  -7,  -6,  -5,  -4,  -3,  -2,  -1,   0,   1,   2,
         3,   4,   5,   6,   7,   8,   9])
>>> a.clip(0, 10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

İle sadece alt yarısını kesebilirsiniz clip(0).

>>> a = numpy.array([1, 2, 3, -4, 5])
>>> a.clip(0)
array([1, 2, 3, 0, 5])

İle sadece üst yarısını kırpabilirsiniz clip(max=n). (Bu, NaNilk parametreye geçmeyi outve türü zorlamak için kullanmayı içeren önceki önerimden çok daha iyi .):

>>> a.clip(max=2)
array([ 1,  2,  2, -4,  2])

Bir başka ilginç yaklaşım da kullanmaktır where:

>>> numpy.where(a <= 2, a, 2)
array([ 1,  2,  2, -4,  2])

Son olarak, aix'in cevabını düşünün . clipBasit işlemleri tercih ederim çünkü kendi kendini belgeliyor, ancak daha karmaşık işlemler için cevabı tercih edilir.


1
a.clip (0) yeterli olacaktır çünkü OP sadece negatif değerleri değiştirmek istiyor. a.clip (0, 10) 10'un üzerindeki her şeyi hariç tutar.
Usagi

1
@Hiett - Daha yeni denedim ve klip bir tane alacak. İlk olarak min.
Usagi

numpy ile bir sürüm sorunu olmalı - benim çıktıma göre: (Pdb) np.clip (w, 0) *** TypeError: clip () en az 3 argüman alır (2 verilen) - oysa: (Pdb) np.clip ( w, 0,1e6) array ([[0., 0.605]])
bph

1
@Hiett, hangi versiyonu numpy? Eğer klibi denedin mi yöntemini ait a? Yerleşik işlev numpy.clipbana aynı hatayı veriyor, ancak yöntem vermiyor.
gönderen

evet, eğer ona bu şekilde derseniz, işe yarıyor gibi görünüyor, örneğin p w.clip (0) array ([[0., 0.605]]) - ne kadar tuhaf?
bph

10

Numpy kullanmadan başka bir minimalist Python çözümü:

[0 if i < 0 else i for i in a]

Ekstra işlev tanımlamaya gerek yok.

a = [1, 2, 3, -4, -5.23, 6]
[0 if i < 0 else i for i in a]

verim:

[1, 2, 3, 0, 0, 6]

1
bu güzel - if ifadesini liste anlayışına koymak için sözdiziminin ne olacağını merak ediyordum - for döngüsünden sonra yapıştırarak ve yalnızca iki değer geri alarak yanlış gidiyordum, örneğin [0, 0] örneğiniz için liste
bph

Başlangıçta liste anlayışını öğrendiğimde ve anlayışımı test etmek için farklı şeyler denediğimde de aynısını yaptım - bunu benim için de for döngüsünden sonra koymak daha sezgisel göründü. Şimdi, bu öyle :) Onu forlistenin her elemanına uygulamadan önce koymak , sonrasına koymak, sadece koşul yerine getirildiğinde sonuç listeye girmesi anlamına gelir.
Levon

2
@Hiett i < 0 ? 0 : iBir liste kavrayışında sadece üçlü operatörü ( C'de) kullanıyor . Daha net hale getirmek için parantezleri yerleştirin [(0 if i < 0 else i) for i in a]. If sonra koymak, liste ifade yapısının filtre bölümünü kullanmaktır. [(i) for i in a if i < 0]yalnızca sıfırdan küçük öğelerin bir listesini döndürür.
Paul S

2
Numpy güçlüdür çünkü hesaplamanın çoğunu derlenmiş c koduyla yapar ve bu nedenle daha hızlıdır. Bu yöntemi diğerleriyle karşılaştırdığımda neredeyse 10 kat hız faktörü farkı buldum (bu daha yavaştır). Dolayısıyla sezgisel ve okuması kolay olsa da, bu kesinlikle hesaplama açısından yoğun değildir.
rspencer

4

Ve yine başka bir olasılık:

In [2]: a = array([1, 2, 3, -4, 5])

In [3]: where(a<0, 0, a)
Out[3]: array([1, 2, 3, 0, 5])

2

İşte NumPy olmadan Python'da yapmanın bir yolu. İstediğinizi döndüren ve bir liste anlama veya harita işlevini kullanan bir işlev oluşturun.

>>> a = [1, 2, 3, -4, 5]

>>> def zero_if_negative(x):
...   if x < 0:
...     return 0
...   return x
...

>>> [zero_if_negative(x) for x in a]
[1, 2, 3, 0, 5]

>>> map(zero_if_negative, a)
[1, 2, 3, 0, 5]

1
bu yoldan gitmişti ama bunu numpy ile yapmanın daha kolay, daha matlab daha az python yolu olması gerektiğini düşündüm (zaten listeler yerine dizileri kullandığım için). klip mükemmel
bph
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.