蟒蛇 3.9
我有一個 numpy ndarray 字串。實際的陣列有數千個字串,但是假設:
words_master = ['CARES' 'BARES' 'CANES' 'TARES' 'PARES' 'BANES' 'BALES' 'CORES' 'BORES'
'MARES']
我正在嘗試創建一個函式,該函式回傳一個串列,其中包含給定字符的字串已被洗掉。這可用作 while 回圈和 if 陳述句:
index = 0
temp = []
while index != len(words_master):
idx = words_master[index]
if 'A' in idx:
temp.append(index)
index = 1
words_master = np.delete(words_master, temp)
由于這仍然是一個 for 回圈和 if 陳述句,我想知道是否可以使用串列理解來提高效率。
我對此的最佳猜測是:
words_master = np.delete(words_master, np.argwhere([x for x, item in enumerate(words_master) if 'A' in item]))
這里的邏輯是 np.delete 將獲取初始陣列,然后洗掉 np.argwhere 設定的索引處的所有專案。但是,它給出了以下輸出:
['CARES' 'BORES' 'MARES']
似乎它忽略了第一個和最后一個元素?
其他奇怪:如果我在專案中使用“關心”,它會回傳串列而不做任何更改:
['CARES' 'BARES' 'CANES' 'TARES' 'PARES' 'BANES' 'BALES' 'CORES' 'BORES'
'MARES']
如果我使用任何其他引數(“MARES”或“M”或“O”),它似乎會回傳沒有第一個單詞的完整串列:
['BARES' 'CANES' 'TARES' 'PARES' 'BANES' 'BALES' 'CORES' 'BORES' 'MARES']
我試過:
- 使用索引,例如使用 (reversed(list(enumerate.. 或將索引串列設為 -1。然而,這些會導致相同型別的模式,但只是被替換了。
- 改用 np.where() ,但我遇到了類似的問題。
我想知道是否有一種干凈的方法來解決這個問題?還是 while 回圈/if 陳述句是最好的選擇?
編輯:對于“為什么不使用串列”的問題,我讀到 numpy 陣列比 python 串列快很多,當我測驗這個相同的 for 回圈時,除了使用帶有 remove() 函式的 python 串列,它慢了 10 倍在更大的資料集上。
uj5u.com熱心網友回復:
import numpy as np
words_master = np.array(['CARES', 'BARES', 'CANES', 'TARES', 'PARES', 'BANES', 'BALES', 'CORES', 'BORES', 'MARES']
是的。這可以更清楚地寫為布爾索引的串列理解。
bad_char = "A"
words_without_char = words_master[[bad_char not in x for x in words_master]]
>>> words_without_char
array(['CORES', 'BORES'], dtype='<U5')
也可以直接列個清單:
>>> [x for x in words_master if bad_char not in x]
['CORES', 'BORES']
uj5u.com熱心網友回復:
argwhere回傳enumerate非零的索引。那不是你想要的。
In [241]: [x for x, item in enumerate(words_master) if 'A' in item]
Out[241]: [0, 1, 2, 3, 4, 5, 6, 9]
In [242]: np.argwhere(_)
Out[242]:
array([[1],
[2],
[3],
[4],
[5],
[6],
[7]])
沒有它,enumerate作業就好了:
In [247]: np.delete(words_master, [x for x, item in enumerate(words_master) if
...: 'A' in item])
Out[247]: array(['CORES', 'BORES'], dtype='<U5')
但是將它的時間與純粹的理解進行比較:
In [248]: timeit np.delete(words_master, [x for x, item in enumerate(words_master) if 'A' in item])
27.8 μs ± 930 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [249]: timeit [word for word in words_master if word.find('A')==-1]
1.73 μs ± 16.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [251]: timeit [word for word in words_master if 'A' not in word]
604 ns ± 2.86 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
列舉的部分delete時間與其他理解大致相同。所以 [248] 中的大部分時間是delete. 雖然是一個陣列函式,但它并不是超級快。它可能比理解更好,但我們仍然沒有擺脫那些。
In [252]: timeit [x for x, item in enumerate(words_master) if 'A' in item]
1.06 μs ± 4.04 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
如果我們從一個字串陣列(而不是串列)開始,直接索引它會更快,而不是遍歷delete:
In [279]: arr = np.array(words_master)
In [280]: arr[['A' not in word for word in arr]]
Out[280]: array(['CORES', 'BORES'], dtype='<U5')
In [281]: timeit arr[['A' not in word for word in arr]]
12.9 μs ± 480 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
但是我們可以通過同時使用陣列和串列(用于迭代)來改進它:
In [282]: timeit arr[['A' not in word for word in words_master]]
6.27 μs ± 245 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
uj5u.com熱心網友回復:
你試過字串方法嗎?
filtered_words_master = [x for x in words_master if x.find('A') != 1]
Something like this?
編輯 試圖解決有關陣列與串列的問題:
def filtering_arrays(arr, substring):
""" Remove elements containing specific substring """
return np.delete(arr, [i for i, item in enumerate(arr) if item.find(substring) == 1])
uj5u.com熱心網友回復:
您要求 numpy,這是一個 numpy 單行解決方案:
import numpy as np
words_master = np.array(['CARES','BARES','CANES','TARES','PARES','BANES','BALES','CORES','BORES','MARES'])
words_without_char=words_master[np.char.find(words_master,"A")==-1]
如果 find 命令沒有找到該字符,則回傳 -1,并且只回傳那些專案
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/416483.html
標籤:
