繁体   English   中英

将许多列表转换为具有预定义数据类型的单个 np 数组的最快方法

[英]Fastest way to turn many lists into single np array with predefined datatypes

有没有比迭代更好(更快)的方法来写入预定义的一维 numpy 数组? 我可以一次写 >1 个元素吗? 那会更快吗?

我尝试填充 arrays 然后使用np.concatenate()但速度明显较慢。

我希望我可以做类似e[0][1:1+len(times)] = times的事情,但这不是我需要的维度中的索引。

这是一些示例代码,要注意的关键是我的列比数据多,我正在创建一个列存储,所以我需要记录空值......

import numpy as np

# quote has arrived with 2 levels
time = 1509980228568000
times = [1509980228528000, 1509980228528000]
prices = [1.80699, 1.80698]
sizes = [100000.0, 250000.0]

# assume this is my 'schema'
number_of_levels = 4
dtypes = [('time', 'uint64'),
          ('bid_time0', 'uint64'), ('bid_time1', 'uint64'), ('bid_time2', 'uint64'), ('bid_time3', 'uint64'),
          ('bid_px0', 'float64'), ('bid_px1', 'float64'), ('bid_px2', 'float64'), ('bid_px3', 'float64'),
          ('bid_size0', 'float64'), ('bid_size1', 'float64'), ('bid_size2', 'float64'), ('bid_size3', 'float64')]
# create empty shell array
e = np.zeros(1, dtype=dtypes)

# add time
e[0][0] = time

# insert bid times
offset = 1
for i in range(min(number_of_levels, len(times))):
    e[0][offset+i] = times[i]

# insert bid prices
offset += number_of_levels
for i in range(min(number_of_levels, len(prices))):
    e[0][offset+i] = prices[i]

# insert bid sizes
offset += number_of_levels
for i in range(min(number_of_levels, len(sizes))):
    e[0][offset+i] = sizes[i]

或者-如果我正在做的事情有更好的方法,我会全神贯注:)

注意:这是一个稍微点头的例子, number_of_levels在实践中更大(但仍然只有~20),

# Create your row
row = [time] + times[:min(number_of_levels, len(times))] + \
    [0] * (number_of_levels - min(number_of_levels, len(times))) + \
    prices[:min(number_of_levels, len(prices))] + \
    [0] * (number_of_levels - min(number_of_levels, len(prices))) + \
    sizes[:min(number_of_levels, len(sizes))] + \
    [0] * (number_of_levels - min(number_of_levels, len(sizes)))

# Create a numpy array
arr = np.array(tuple(row), dtype=dtypes)

# Create a new array with supposedly with new data
arr2 = np.array(tuple(row), dtype=dtypes)

# Stack them up
arr3 = np.vstack((arr, arr2))

所以你已经创建了一个包含 1 个元素和 13 个字段的数组

In [241]: e                                                                                          
Out[241]: 
array([(55309248, 0, 0, 0, 0, 0., 0., 0., 0., 0., 0., 0., 0.)],
      dtype=[('time', '<u8'), ('bid_time0', '<u8'), ('bid_time1', '<u8'), ('bid_time2', '<u8'), ('bid_time3', '<u8'), ('bid_px0', '<f8'), ('bid_px1', '<f8'), ('bid_px2', '<f8'), ('bid_px3', '<f8'), ('bid_size0', '<f8'), ('bid_size1', '<f8'), ('bid_size2', '<f8'), ('bid_size3', '<f8')])

您可以将元组分配给该数组的元素 - 只需匹配字段数:

In [246]: e[0]                                                                                       
Out[246]: (55309248, 0, 0, 0, 0, 0., 0., 0., 0., 0., 0., 0., 0.)
In [247]: e[0]=tuple(range(13))                                                                      
In [248]: e                                                                                          
Out[248]: 
array([(0, 1, 2, 3, 4, 5., 6., 7., 8., 9., 10., 11., 12.)],
      dtype=[('time', '<u8'), ('bid_time0', '<u8'), ('bid_time1', '<u8'), ('bid_time2', '<u8'), ('bid_time3', '<u8'), ('bid_px0', '<f8'), ('bid_px1', '<f8'), ('bid_px2', '<f8'), ('bid_px3', '<f8'), ('bid_size0', '<f8'), ('bid_size1', '<f8'), ('bid_size2', '<f8'), ('bid_size3', '<f8')])

我不会尝试从变量中计算出范围和映射的组合。 那是你的任务。

结构化数组的数据可以是元组列表的形式。 但通常记录比字段多得多,因此按字段为所有记录分配值相对有效。

定义多维字段可能更容易:

In [249]: dt = [('time', 'uint64'), 
     ...:    ('bid_time', 'uint64', (4,)), ('bid_px', 'float64', (4,)), ('bid_size', 'float64', (4,))] 
                                                                                      
In [250]: dt                                                                                         
Out[250]: 
[('time', 'uint64'),
 ('bid_time', 'uint64', (4,)),
 ('bid_px', 'float64', (4,)),
 ('bid_size', 'float64', (4,))]
In [251]: e = np.zeros(3, dt)                                                                        
In [252]: e                                                                                          
Out[252]: 
array([(0, [0, 0, 0, 0], [0., 0., 0., 0.], [0., 0., 0., 0.]),
       (0, [0, 0, 0, 0], [0., 0., 0., 0.], [0., 0., 0., 0.]),
       (0, [0, 0, 0, 0], [0., 0., 0., 0.], [0., 0., 0., 0.])],
      dtype=[('time', '<u8'), ('bid_time', '<u8', (4,)), ('bid_px', '<f8', (4,)), ('bid_size', '<f8', (4,))])
In [253]: e['time']=[1,2,3]                                                                          
In [254]: e['bid_size']                                                                              
Out[254]: 
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

然后你可以一次分配多个值

e['bid_time'] = ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM