簡體   English   中英

使用Numpy布爾數組索引Python列表

[英]Index Python List with Numpy Boolean Array

有沒有一種方法可以使用numpy布爾數組為x = ['a','b','c']等python列表建立索引? 我目前遇到以下錯誤: TypeError: only integer arrays with one element can be converted to an index

通過[]索引會秘密調用對象的__getitem__方法。 對於使用純Python實現的對象,您可以使用任何適合您需要的函數簡單地覆蓋此方法。 但是,列表是用C實現的,因此不允許您替換list.__getitem__ 因此,沒有直接的方法可以執行您的請求。

但是,您可以從列表中創建一個NumPy數組,然后對此進行NumPy樣式的布爾索引:

import numpy as np

x = ['a', 'b', 'c']

mask = np.array([True, False, True])
x_arr = np.asarray(x, dtype=object)
output = x_arr[mask]  # Get items
x_arr[mask] = ['new', 'values']  # Set items

不幸的是, np.asarray無法簡單地查看列表,因此僅復制了列表。 這意味着將新值分配給x_arr的元素時,原始x不變。

如果您確實希望對列表使用NumPy布爾索引的全部功能,則必須編寫一個從頭開始執行此操作的函數,並且您將無法使用[]索引語法。

In [304]: ['a','b','c'][[2,1,0]]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-304-c04b1f0621a3> in <module>()
----> 1 ['a','b','c'][[2,1,0]]

TypeError: list indices must be integers or slices, not list

清單理解路線

In [306]: [i for i,j in zip(['a','b','c'],[True, False, True]) if j]
Out[306]: ['a', 'c']

陣列路線

In [308]: np.array(['a','b','c'])[np.array([True, False, True])]
Out[308]: 
array(['a', 'c'], 
      dtype='<U1')

返回目錄:

In [309]: np.array(['a','b','c'])[np.array([True, False, True])].tolist()
Out[309]: ['a', 'c']

但請注意,如果您的列表包含對象,而不是數字或字符串。 這可能不會保留鏈接。

operator模塊具有itemgetter功能

In [321]: operator.itemgetter(*[2,0,1])(list('abc'))
Out[321]: ('c', 'a', 'b')

但是在幕后,它只是像迭代器一樣的列表理解。 而且我不會立即看到布爾版本。

map(x.__getitem__,np.where(mask)[0])

或者,如果您想了解列表

[x[i] for i in np.where(mask)[0]]

這使您不必遍歷整個列表,尤其是在mask稀疏的情況下。

您是否需要將其作為列表。 由於您要使用numpy數組的索引行為,因此,如果您實際使用numpy數組,則對於其他讀取您的代碼的人來說更有意義。

也許嘗試使用dtype ='a'的數組? 例如,在下面的代碼中,

x = sp.array(['a', 'b', 'c'], dtype='a')
print(x)
print(x=='c')
print(x[x=='c']).

這將返回以下數組,

['a' 'b' 'c']
[False False  True]
['c'].

分配也會像您期望的那樣工作,

x[x=='c'] = 'z'
print(x).  

這將返回修改后的數組,

['a' 'b' 'z'].

唯一需要注意的是,數組的元素不能超過分配的長度。 在這里它被指定為dtype ='a'。 您可以根據需要使用dtype ='a5'或dtype ='aN'。 數組的所有元素必須是短於最大長度的字符串。

如果傳遞的字符串太長,則會截斷結尾,如以下示例,其中dtype設置為'a2':

x = sp.array(['abc', 'bcd', 'cde'], dtype='a2')
print(x), 

這使,

['ab' 'bc' 'cd'].

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM