0

我用 ndarray 存储刻度,每个刻度都有一个 utc_timestamp[str] 作为索引,刻度价格/vols 作为值。因此,我有一个包含 2 个不同 dtypes(str 和 float)的数组。这就是我将它存储为 np.recarray 的方式

data = np.recarray((100,), dtype=[('time':'U23'),('ask1':'f'),('bid1':'f')])
tick = ['2021-04-28T09:38:30.928',14.21,14.2]

# assigning this tick to the end of data, wield
%%timeit
  ...: data[-1] = np.rec.array(tick)
  ...: 
1.38 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

每个循环需要 1.38 毫秒!另外,我无法使用 data[-1] = tick 设置最后一行,这会引发 ValueError: setting an array element with a sequence

让我们尝试简单的 ndarray,假设我有 2 个单独的数组,一个用于 str,一个用于 float

%%timeit
  ...: data[:,-1]=tick[1:]
  ...: 
15.2 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

看?快了 90 倍!这是为什么?

4

1 回答 1

0

我的时间好多了:

In [503]: timeit data[-1] = np.rec.array(tick)
64.4 µs ± 321 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

np.rec.array(tick)创建一个dtype=[('f0', '<U23'), ('f1', '<f8'), ('f2', '<f8')]). 如果我使用最终的 dtype,我的速度会更快。

In [504]: timeit data[-1] = np.rec.array(tick, data.dtype)
31.1 µs ± 22.9 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

大部分时间都在创建 1 项 recarray:

In [516]: %timeit x = np.rec.array(tick, data.dtype)
29.9 µs ± 41.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

改为制作结构化数组:

In [517]: %timeit x = np.array(tuple(tick), data.dtype)    
2.71 µs ± 15.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

In [519]: timeit data[-1] = np.array(tuple(tick), data.dtype)
3.58 µs ± 11.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

所以完全跳过recarray

In [521]: data = np.zeros((100,), dtype=[('time','U23'),('ask1','f'),('bid1','f')])
     ...: tick = ('2021-04-28T09:38:30.928',14.21,14.2)
In [522]: data[-1] = np.array(tick, data.dtype)
In [523]: data[-2:]
Out[523]: 
array([('',  0.  ,  0. ), ('2021-04-28T09:38:30.928', 14.21, 14.2)],
      dtype=[('time', '<U23'), ('ask1', '<f4'), ('bid1', '<f4')])

我认为recarray在很大程度上已经被结构化数组所取代。recarray 添加的主要功能是将字段作为属性进行寻址

data.time, data.ask1
data['time'], data['ask1']

您的示例表明这recarray会减慢速度。

编辑

元组刻度可以直接赋值,无需额外转换:

In [526]: timeit data[-1] = tick
365 ns ± 0.247 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
于 2021-04-28T06:50:13.117 回答