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.

Jawaban:


137

Anda sudah setengah jalan. Mencoba:

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

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

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.


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]

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

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]

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.