python - 如何提高使用来自迭代器的数据加载 ndarray 的效率?
问题描述
我有一个迭代器,其中包含 13,104,640 项三元组(i,j,value)
。i
是行的索引,而表示j
矩阵的列的索引。我还声明了一个所有项目都是一个的 2D ndarray。当我使用 for 循环加载带有迭代器中项目的 2D ndarray 时,时间消耗非常高。
如何提高使用该迭代器的项目加载 2D ndarray 的效率?
下面是我的 python3 代码的补丁:
nn = 5120
prxy_matrix = np.ones((nn, nn), dtype=float)
for i,j,p in iterator_A:
prxy_matrix[i][j] = p
prxy_matrix[j][i] = p
我可以使用一些矩阵操作,例如将数据作为一些块移动吗?
解决方案
当您生成完整的上下三角形并可以控制元素的顺序时,最简单的方法是scipy.spatial.distance.squareform
. squareform
期望值逐行,与您从中获得的顺序相同itertools.combinations
。
从迭代器中获取数据的最快方法是np.fromiter
:
import numpy as np
from operator import itemgetter
from scipy.spatial.distance import squareform
import itertools as it
模拟数据源:
def source(n):
for i,j in it.combinations(range(n),2):
yield i,j,(i-j)/2
原始代码:
def OP():
prxy_matrix = np.ones((nn, nn), dtype=float)
for i,j,p in source(nn):
prxy_matrix[i][j] = p
prxy_matrix[j][i] = p
return prxy_matrix
我的建议:
def pp():
data = np.fromiter(map(itemgetter(2),source(nn)),float,(nn*(nn-1))//2)
prxy_matrix = squareform(data)
prxy_matrix.ravel()[::nn+1] = 1
return prxy_matrix
这已经相当快了,但是我们在浪费时间创建和丢弃元组(坐标是多余的,所以我们甚至不读取它们)。由于您似乎可以控制生成器,因此请考虑仅生成数据:
def val_only(n):
for i,j in it.combinations(range(n),2):
yield (i-j)/2
def pp2():
data = np.fromiter(val_only(nn),float,(nn*(nn-1))//2)
prxy_matrix = squareform(data)
prxy_matrix.ravel()[::nn+1] = 1
return prxy_matrix
几个时间:
from timeit import timeit
nn = 1000
print(timeit(OP,number=10))
print(timeit(pp,number=10))
print(timeit(pp2,number=10))
# next three are to give a rough idea how much of the time is due to the iterator alone
print(timeit(lambda:all(source(nn)),number=10))
print(timeit(lambda:sum(val_only(nn)),number=10))
print(timeit(lambda:sum(it.chain.from_iterable(source(nn))),number=10))
产量:
3.4740988661069423
1.3367053079418838
0.7327171310316771
0.7123838479164988
0.5886694570071995
1.1725806428585202
推荐阅读
- php - Laravel JWT - 使用有效的登录令牌未经身份验证
- reactjs - 为什么在 api 调用后 useEffect 不更新值?
- javascript - 在网格单元javascript中获取复选框值
- python - How to conditionally add items to a series in a dataframe
- here-api - 此处观察 api 中的风速指标是什么?
- r - 对多条 geom_rect 线使用 override.aes 时遇到问题
- php - Laravel API 不反映直接在数据库中所做的更改
- javascript - 如何序列化包含 blob 图像的 FormData?
- javascript - innerHTML 创建一个新元素,而不是替换目标元素的 innerHTML
- dynamics-crm - 从 Dynamics CRM 2011 升级到 CRM 2016 后,表单和插件出现奇怪问题