2017-03-01 107 views
0

我試圖用numpy繪製一些複雜的函數。一些工作代碼示例:Python:數組與非數組的元素比較

import numpy as np 
from PIL import Image 

size = 1000 

w = np.linspace(-10, 10, size) 
x, y = np.meshgrid(w, w) 
r = x + 1j*y 

def f(q): 
    return np.angle(q) 

z = f(r) 

normalized = ((255/(np.amax(z) - np.amin(z)))*(z+abs(np.amin(z)))).astype(int) 

data = [i for j in normalized for i in j] 

img = Image.new('L', (size, size)) 
img.putdata(data[::-1]) #pixels are done bottom to top 
img.show() 

然而,假設我要的函數f有它的一個簡單的對比,就像這樣:

def f(q): 
    if np.abs(q) < 4: 
     return 1 
    else: 
     return 0 

我得到的錯誤

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

對於np.abs(q)< 4檢查。

我做了一些挖掘並意識到這是因爲Python正在對整個r數組執行操作,並且它無法將數組與一個整數進行比較。所以,我試圖尋找方法來進行元素比較。

This page看起來前途無量:它說我可以用np.less做逐元素的比較(A,B),所以我試圖

def f(q): 
    if np.less(np.abs(q), 4): 
     return 1 
    else: 
     return 0 

,並得到了相同的ValueError異常。似乎np.less()的兩個參數都需要是相同大小的數組。

我想要的是將我的數組的每個元素與單個非數組數量的進行比較。我想我可以做一個相同大小的虛擬數組,填充相同的4,但必須有一個更優雅的方式來做到這一點。

回答

0

關鍵是要返回一個數組值,而不是試圖將一個數組強制轉換爲一個布爾值,這就是if (some_array):一直試圖做的事情。有沒有明確的方式來決定什麼布爾np.array([True, False])應該轉換,它甚至不嘗試。

所以不要分支:

def f(q): 
    return abs(q) < 4 

給像

>>> f(np.array([1,3,5])) 
array([ True, True, False], dtype=bool) 

數組,它爲數字將像

>>> f(np.array([1,3,5])).astype(int) 
array([1, 1, 0]) 

,並給

circle

+0

如果我需要它來分支呢?我試圖做的真正問題是繪製Mandelbrot分形。這需要檢查每個點是否在某個函數迭代下發散,並且我需要它在這兩種情況下做不同的事情。 – dain

+0

@dain:那麼你需要以不需要單獨分支的方式重寫你的公式(例如'np.where(np.array([1,2,3])> 2,10,11 )'),或者以標量形式寫公式,然後使用'np.vectorize'。你會失去一些表演。與後者。除此之外:像這樣的問題是爲什麼保持你的帖子類似於你的實際目標通常更好。如果你簡化得太早,那麼你會得到一個你實際詢問的問題的答案(「我想要的是將我的數組的每個元素與單個非數組數量進行比較」),而不是你想要的,不問。 – DSM