Ganti nilai negatif dalam larik numpy

90

Apakah ada cara sederhana untuk mengganti semua nilai negatif dalam array dengan 0?

Saya memiliki blok lengkap tentang cara melakukannya menggunakan array NumPy.

Misalnya

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

Saya harus kembali

[1, 2, 3, 0, 5]

a < 0 memberikan:

[False, False, False, True, False]

Di sinilah saya terjebak - bagaimana menggunakan array ini untuk memodifikasi array asli.

bph
sumber

Jawaban:

137

Anda sudah setengah jalan. Mencoba:

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

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

Coba 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])

Anda hanya dapat memotong bagian bawah dengan clip(0).

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

Anda hanya dapat memotong bagian atas dengan clip(max=n). (Ini jauh lebih baik daripada saran saya sebelumnya, yang melibatkan penerusan NaNke parameter pertama dan menggunakan outuntuk memaksa tipe.):

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

Pendekatan menarik lainnya adalah dengan menggunakan where:

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

Akhirnya, pertimbangkan jawaban aix . Saya lebih suka clipoperasi sederhana karena ini mendokumentasikan sendiri, tetapi jawabannya lebih disukai untuk operasi yang lebih kompleks.

pengirim
sumber
1
a.clip (0) sudah cukup karena OP hanya ingin mengganti nilai negatif. a.clip (0, 10) akan mengecualikan apa pun di atas 10.
Usagi
1
@Hiett - Saya baru saja mencobanya dan klip akan mengambil satu. Pertama diasumsikan min.
Usagi
harus menjadi masalah versi dengan numpy - inilah ouptut saya: (Pdb) np.clip (w, 0) *** TypeError: clip () membutuhkan setidaknya 3 argumen (2 diberikan) - sedangkan: (Pdb) np.clip ( w, 0,1e6) array ([[0., 0.605]])
bph
1
@Hiett, versi berapa numpy? Apakah Anda mencoba klip metode dari a? Fungsi numpy.clipbawaan memberi saya kesalahan yang sama, tetapi metode tidak.
pengirim
yeh jika Anda menyebutnya seperti itu tampaknya berhasil, misalnya p w.clip (0) array ([[0., 0.605]]) - bagaimana aneh?
bph
10

Solusi Python minimalis lainnya tanpa menggunakan numpy:

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

Tidak perlu mendefinisikan fungsi tambahan apa pun.

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

hasil:

[1, 2, 3, 0, 0, 6]
Levon
sumber
1
itu bagus - saya bertanya-tanya apa sintaksnya untuk meletakkan pernyataan if di dalam pemahaman daftar - saya salah dengan menempelkannya setelah perulangan for dan hanya kemudian mendapatkan dua nilai kembali, misalnya [0, 0] untuk contoh Anda daftar
bph
Saya melakukan hal yang sama ketika saya awalnya belajar tentang pemahaman daftar dan mencoba berbagai hal untuk menguji pemahaman saya - tampaknya lebih intuitif untuk meletakkannya setelah loop for untuk saya juga. Sekarang, bagaimanapun, ini terjadi :) Menempatkannya sebelum formenerapkannya ke setiap elemen daftar, meletakkannya setelah, berarti hanya jika kondisi terpenuhi apakah itu masuk ke daftar yang dihasilkan.
Levon
2
@Hiett Ini hanya menggunakan operator terner ( i < 0 ? 0 : idalam C) di dalam pemahaman daftar. Beri tanda kurung agar lebih jelas [(0 if i < 0 else i) for i in a]. Menempatkan if after menggunakan bagian filter dari konstruksi ekspresi daftar. [(i) for i in a if i < 0]hanya akan mengembalikan daftar item yang kurang dari nol.
Paul S
2
Numpy sangat powerful karena ia melakukan banyak komputasi dengan mengkompilasi kode c dan dengan demikian lebih cepat. Membandingkan metode ini dengan yang lain, saya menemukan perbedaan faktor kecepatan hampir 10 kali lipat (ini lebih lambat). Jadi meski intuitif dan mudah dibaca, ini jelas bukan untuk komputasi intensif.
rspencer
4

Dan kemungkinan lain:

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

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

Berikut cara melakukannya dengan Python tanpa NumPy. Buat fungsi yang mengembalikan apa yang Anda inginkan dan gunakan pemahaman daftar, atau fungsi peta .

>>> 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]
Kekoa
sumber
1
telah turun rute ini tetapi berpikir pasti ada cara yang lebih mudah, lebih matlab kurang python untuk melakukannya dengan numpy (karena saya menggunakan array daripada daftar). klip sempurna
bph