![](/img/trans.png)
[英]What's the difference when indexing a numpy array between using an integer and a numpy scalar?
[英]What's the time complexity of indexing a numpy array directly
我假設當有一個 numpy 數組時,讓我們說
>>>>nArray
array([[ 23425. , 521331.40625],
[ 23465. , 521246.03125],
[ 23505. , 528602.8125 ],
[ 23545. , 531934.75 ],
[ 23585. , 534916.375 ],
[ 23865. , 527971.1875 ]])
直接索引必須非常有效。
我想像nArray[0, 1] = 69696420
必須使用哈希表,它的時間復雜度接近 O(1)。 那正確嗎?
更新
正如兩個答案所指出的,索引 numpy 數組不涉及散列。 兩個答案都清楚地解釋了索引是如何發生的。
更新 2
我添加了一個簡單的基准測試來證明答案的有效性
不涉及哈希表。 Numpy數組就是數組,顧名思義,地址是這樣計算的:
address of nArray[x, y] = base address + A * x + B * y
為了通過測試對 Ami 的答案添加一些額外的驗證,我從一個僅使用直接索引進行插入的 numpy 數組創建了一個簡單的循環緩沖區。 基本上每次插入只會改變隊列中最舊元素的值。
該代碼並非完全沒有錯誤,但它可以作為一些簡單的性能基准測試的基礎。
import math
import numpy as np
class CircFifo():
"""
helper class, uses a numpy array to provide a circular fixed size fifo
interface.
put(element): removes the oldest element and
places a new one
get(): returns the oldest entry
empty(): returns true if fifo is empty
full(): returns true if fifo is full
"""
def __init__(self, size):
self.array = np.empty(shape=(size, 2))
self.size = size
self.array[:] = np.NAN
self.top = 0
self.bottom = 0
def put(self, row):
self.array[self.top, :] = row
self.top += 1
if self.top == self.size:
self.top = 0
def get(self):
if not math.isnan(self.array[self.bottom, 0]):
row = copy.deepcopy(self.array[self.bottom, :])
self.array[self.bottom, :] = float('NaN')
self.bottom += 1
if self.bottom == self.size:
self.bottom = 0
if math.isnan(self.array[self.bottom, 0]):
self.bottom = 0
self.top = 0
return row
def empty(self):
if math.isnan(self.array[self.bottom, 0]):
return True
else:
return False
def full(self):
if self.size - np.count_nonzero(
np.isnan(self.array[:, 0])) == self.size:
return True
else:
return False
帖子中答案的正確性似乎通過我運行的一個簡單測試得到了確認。 我針對 deque 對象測試了插入性能。 即使對於 1000 次插入雙端隊列,它也用作動態而非靜態數據結構(與我的靜態循環先入先出相反),也明顯優於循環先入先出。
這是我運行的簡單測試
In [5]: import time
In [6]: circFifo = CircFifo(300)
In [7]: elapsedTime = 0
In [8]: for i in range(1, 1000):
...: start = time.time()
...: circFifo.put(np.array([[52, 12]]))
...: elapsedTime += time.time() - start
...:
In [9]: elapsedTime
Out[9]: 0.010616540908813477
In [21]: queue = deque()
In [22]: elapsedTime = 0
In [23]: for i in range(1, 1000):
....: start = time.time()
....: queue.append(np.array([[52, 12]]))
....: elapsedTime += time.time() - start
....:
In [24]: elapsedTime
Out[24]: 0.00482630729675293
我知道這個基准測試的信息量並不大,但很明顯 deque 速度要快得多。 對於至少插入的數量。
我希望如果在 C 中使用靜態數組實現圓形 fifo,它就不會輕易被超越。 因為基本上 C 的靜態數組是最簡單的,可用的數據結構開銷較少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.