![](/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.