2012-02-07 45 views
3

我有3個表xyz和我一起繪製出來:Python的子表的條件

ax.plot3D(x, y, z, linestyle = 'None', marker = 'o'). 

什麼是僅積點這裏x > 0.5最簡單的方法?

(我的問題是如何在一個條件下定義一個子列表,而無需在該列表上進行for循環)。

回答

1

這是不可能的列表中的每個元素上驗證條件不iterati至少一次。條件是中國率先後,您可以在這裏使用numpy的容易獲得的元素,做:

import numpy 
x = [0.0, 0.4, 0.6, 1.0] 
y = [0.0, 2.2, 1.5, 1.6] 
z = [0.0, 9.1, 1.0, 0.9] 
res = numpy.array([[x[i], y[i], z[i]] for i in xrange(len(x)) if x[i] > 0.5]) 
ax.plot3D(res[:,0], res[:,1], res[:,2], linestyle="None, marker='o'") 
3

我不知道你爲什麼避免循環遍歷列表,我假設你想在其他列表中的相關點也刪除。

>>> x = [0.0, 0.4, 0.6, 1.0] 
>>> y = [0.0, 2.2, 1.5, 1.6] 
>>> z = [0.0, 9.1, 1.0, 0.9] 
>>> zip(x,y,z) 
[(0.0, 0.0, 0.0), (0.4, 2.2, 9.1), (0.6, 1.5, 1.0), (1.0, 1.6, 0.9)] 
>>> [item for item in zip(x,y,z) if item[0] > 0.5] 
[(0.6, 1.5, 1.0), (1.0, 1.6, 0.9)] 

將列表分離成它的組成列表需要以某種方式循環列表。

+3

分離列表返回到各列表可以與另一個調用拉鍊完成= [項目在zip(x,y,z)中的項目,如果項目[0]> 0.5]; zip(* f)' – lvc 2012-02-07 11:05:24

+0

@lvc我喜歡這樣!您應該添加,作爲答案,它應該被接受! – 2012-02-07 11:08:20

3

一個簡單的列表理解是不夠的去除(X,Y,Z)元組,如果x < = 0.5,你必須做的多一點,我用operator.itemgetter第二部分:

from operator import itemgetter 

result = [(a, b, c) for a,b,c in zip(x,y,z) if a > 0.5] # first, remove the triplet 
x = itemgetter(0)(result) # then grab from the new list the x,y,z parts 
y = itemgetter(1)(result) 
z = itemgetter(2)(result) 

ax.plot3D(x, y, z, linestyle="None, marker='o') 

編輯: 繼升級@shenshei建議我們可以用一個線實現它:

ax.plot3D(
    *zip(*[(a, b, c) for a,b,c in zip(x,y,z) if a > 0.5]), 
    linestyle="None, 
    marker='o' 
) 
+1

你也可以做'x,y,z = zip(* result)' – shenshei 2012-02-07 11:07:37

+0

不應該是:'x = [itemgetter(0)(point)for result in result]'? – 2012-02-07 11:27:26

+0

@shenshei:我接受你的評論,並將其用於單行:) – 2012-02-07 12:54:29

1

我不想偷LVC的風頭,但這裏是他們的答案變體:

>>> x = [0.1, 0.6, 0.2, 0.8, 0.9] 
>>> y = [0.3, 0.1, 0.9, 0.5, 0.8] 
>>> z = [0.9, 0.2, 0.7, 0.4, 0.3] 
>>> 
>>> a, b, c = zip(*filter(lambda t: t[0] > 0.5, zip(x, y, z))) 
>>> print a, "\n", b, "\n", c 
(0.6, 0.8, 0.9) 
(0.1, 0.5, 0.8) 
(0.2, 0.4, 0.3) 
>>> ax.plot3D(a, b, c, linestyle = 'None', marker = 'o') 
1

根據@StephenPaulger的建議重新發布我的評論。您可以用生成器表達式和幾個調用的做到這一點內置zip()

x = [0.0, 0.4, 0.6, 1.0] 
y = [0.0, 2.2, 1.5, 1.6] 
z = [0.0, 9.1, 1.0, 0.9] 

points = (point for point in zip(x, y, z) if point[0] > 0.5) 
x, y, z = zip(*points) 

你也可以使用列表修真0​​如果你想,但 - 假設Python 3中,其中zip()沒有更長的時間預先計算完整列表時調用 - 這可能會傷害您的內存使用和速度,特別是如果點數很大。

2

可能使用numpy將提供最清潔的方法。但是,您將需要具有列表/陣列xyz作爲numpy陣列。因此,首先這些列表轉換爲numpy的數組:

import numpy as np 
x = np.asarray(x) 
y = np.asarray(y) 
z = np.asarray(z) 

現在計算滿足您的條件元素的索引數組:

idx = np.where(x > 0.5) 

注:另外,你可以計算的布爾掩碼:idx=x>0.5(這不會改變在下一個ax.plot3D聲明中使用idx)。

使用這些指標在xy,並且z滿足所需條件,只選擇那些具體點:`F:

ax.plot3D(x[idx], y[idx], z[idx], linestyle = 'None', marker = 'o')