2016-03-09 56 views
2

我有一個數字,我切片列表,使得(使用例如數據):if語句,而切片

midpoint = [[0.2], [0.5], [0.6]] 
Values = [[0.1, 0.3, 0.6, 0.8], [0.2,0.3,0.5,0.7], [0.2,0.5,0.6,0.9]] 
numbers = numpy.arange(0, len(Values), 1) 

我然後有一個循環,發現從所述第一值的numbers索引位置即大於或小於midpoint的值。我有:

for i in range(len(Values)): 
    indexgtr = numbers[Values[i]>=midpoint[i]][-1] # The position of the first number larger than the midpoint 
    indexlt = numbers[Values[i]<=midpoint[i]][0] # The position of the first number larger than the midpoint 

然後,我使用這些索引位置從我有一些其他列表返回值。

我的問題是,有時候沒有價值已超過中點所以indexgtr或大或小或indexlt返回一個空列表[]和我得到的錯誤IndexError: index 0 is out of bounds for axis 0 with size 0

有什麼我可以補充說,將抓住這一點,並將值0替換爲空列表?

+0

我獲得的錯誤與您的錯誤不同,並且我獲得的運行代碼的錯誤與我的預期相同。首先,表達式'Values [i]> = midpoint [i]'將list與一個標量值進行比較,在Python 2中,這隻返回一個布爾值(Python 3給出了無法定義的類型錯誤)。所以如果它是'True',你正在訪問'numbers [1]',如果它'False'正在訪問'numbers [0]',並且*然後*試圖進一步訪問'numbers [1] [ - 1 ]'或'numbers [0] [ - 1]',這會給出一個錯誤,因爲'numbers [i]'是一個不能爲每個'i'索引的標量。 – ely

+0

上面的數據僅僅是一個例子,因爲我的真實數據非常大且更復雜。我明白它會返回一個布爾值,但它不僅僅是'False'的True,而是更多的[[True,True,True,False,False,False],具體取決於列表的長度。然後這會適當地分割'numbers'並根據需要將索引位置'[0]'或'[-1]'交給我,除非我錯了? –

回答

0

可以得到想要的結果向量化和使用argmax沿着第二軸:

>>> midpoint = np.array([[0.2], [0.5], [0.6], [0.3]]) 
>>> values = np.array([[0.1, 0.3, 0.6, 0.8], 
         [0.2, 0.3, 0.5, 0.7], 
         [0.2, 0.5, 0.6, 0.9], 
         [0.3, 0.1, 0.8, 0.9]]) 

>>> (values > midpoint).argmax(axis=1) # indexgtr vectorized 
array([1, 3, 3, 2]) # first >= occurrence for each row 

>>> (values < midpoint).argmax(axis=1) 
array([0, 0, 0, 1]) # first < occurrence for each row 

注:我已經取代了<=>=<>展現更好的矢量結果。請注意,對於<的情況,第一行沒有任何小於0.2的列,但0已返回(因爲它是第一次出現的情況,因爲它是充滿False的行)。

.argmax(axis=1)找到橫跨第2軸的最大值的位置。由於它是一個布爾數組,它返回第一個True事件。

+0

好,但我認爲'np.argwhere'比'np.argmax'更合適,因爲你正在處理一個布爾數組 – wim

+0

@wim這將返回所有元素的索引(滿足條件)並且需要一個額外的後處理步驟來過濾每一行的第一個元素。 –

0

有多種方法,你可以表達測試:

for i in range(len(Values)): 
    indexgtr = numbers[Values[i]>=midpoint[i]] 
    if indexgtr.shape[0]==0: 
     indexgtr = 0 
    else: 
     indexgtr = indexgtr[-1] 
    indexlt = numbers[Values[i]<=midpoint[i]] 
    if indexlt.shape[0]:  # alt expression 
     indexlt = indexlt[0] 
    else: 
     indexlt = 0 
    # indexlt = indexlt[0] if len(indexlt) else 0 

他們都有點羅嗦,但我不認爲他們是昂貴的。你在這裏沒有使用矢量做任何事情 - 除了從numbers中選擇子值。由於numbers已排序,因此您也可以使用minmax做些事情,而不是選擇第一個或最後一個值。

測試表達與喜歡的東西:

In [39]: x=np.arange(0) 
In [40]: x[0] if len(x) else 0 
Out[40]: 0 

我以爲你會在做一些與此環路indexgtrindexlt上移動到下一個i之前。

+0

這實際上是我最終做的。實際上,我將這個值附加到一個新的列表中,所以就像你的回答一樣,我設置了一個檢查數組長度的if循環。如果它是空的,我附加0.0值,否則我跑我的代碼。它也是羅嗦的,但它並不昂貴。 –