numpy 数组:快速填充和提取数据

2023-11-30

请参阅此问题底部的重要说明。

我正在使用 numpy 来加速经度/纬度坐标的一些处理。不幸的是,我的 numpy“优化”使我的代码运行速度提高了大约 5 倍slowly比它在不使用 numpy 的情况下运行。

瓶颈似乎在于用我的数据填充 numpy 数组,然后在完成数学转换后提取该数据。为了填充数组,我基本上有一个像这样的循环:

point_list = GetMyPoints() # returns a long list of ( lon, lat ) coordinate pairs
n = len( point_list )
point_buffer = numpy.empty( ( n, 2 ), numpy.float32 )

for point_index in xrange( 0, n ):
    point_buffer[ point_index ] = point_list[ point_index ]

该循环仅在对其进行操作之前填充 numpy 数组,速度非常慢,比没有 numpy 的整个计算慢得多。 (也就是说,这不仅仅是 python 循环本身的缓慢,而且显然在实际将每个小数据块从 python 传输到 numpy 时存在巨大的开销。)另一端也有类似的缓慢;处理完 numpy 数组后,我在循环中访问每个修改的坐标对,再次如下

some_python_tuple = point_buffer[ index ]

同样,提取数据的循环比没有 numpy 的整个原始计算慢得多。那么,我如何实际填充 numpy 数组并从 numpy 数组中提取数据,而不会违背首先使用 numpy 的目的?

我正在使用 C 库从形状文件中读取数据,该库将数据作为常规 python 列表提供。我知道,如果库向我提供了 numpy 数组中已有的坐标,则不需要“填充”numpy 数组。但不幸的是,我的数据起点是一个常规的 python 列表。更重要的是,一般来说,我想了解如何使用 python 中的数据快速填充 numpy 数组。

澄清

上面显示的循环实际上过于简单化了。我在这个问题中这样写是因为我想专注于我所看到的尝试在循环中缓慢填充 numpy 数组的问题。我现在明白这样做只是缓慢的。

在我的实际应用程序中,我拥有的是坐标点的形状文件,并且我有一个 API 来检索给定对象的点。大约有 200,000 个对象。所以我反复调用一个函数GetShapeCoords( i )获取对象 i 的坐标。这将返回一个列表列表,其中每个子列表都是经度/纬度对的列表,它是列表列表的原因是某些对象是多部分的(即多多边形)。然后,在我的原始代码中,当我读取每个对象的点时,我通过调用常规 python 函数对每个点进行转换,然后使用 PIL 绘制转换后的点。整个过程花了大约 20 秒来绘制所有 200,000 个多边形。并不可怕,但还有很大的改进空间。我注意到这 20 秒中至少有一半花在了转换逻辑上,所以我想我应该在 numpy 中这样做。我最初的实现只是一次读入一个对象,然后将子列表中的所有点不断附加到一个大的 numpy 数组中,然后我可以在 numpy 中进行数学运算。

所以,我现在明白,简单地将整个 python 列表传递给 numpy 是设置大数组的正确方法。但就我而言,我一次只读取一个对象。所以我能做的一件事就是在一个大的Python列表列表中不断地添加点。然后,当我以这种方式编译了一些大量对象的点(例如 10000 个对象)时,我可以简单地将怪物列表分配给 numpy。

所以我现在的问题是三个部分:

(a) numpy 真的可以接受那么大的、不规则形状的列表列表,并快速快速地读取它吗?

(b) 然后我希望能够变换该怪物树叶子中的所有点。例如,获取 numpy 的表达式是什么,“进入每个子列表,然后进入每个子子列表,然后对于在这些子子列表中找到的每个坐标对,将第一个(lon 坐标)乘以 0.5”?我可以这样做吗?

(c) 最后,我需要取回这些转换后的坐标以便绘制它们。

下面温斯顿的回答似乎暗示了我如何使用 itertools 来完成这一切。我想做的与温斯顿所做的非常相似,将列表展平。但我不能完全把它弄平。当我去绘制数据时,我需要能够知道一个多边形何时停止以及下一个多边形何时开始。所以,我认为如果有一种方法可以用特殊的坐标对(例如(-1000,-1000)或类似的东西)快速标记每个多边形(即每个子列表)的末端,我就可以让它工作。然后我可以像温斯顿的答案一样用 itertools 进行展平,然后在 numpy 中进行转换。然后我需要使用 PIL 从点到点进行实际绘制,在这里我想我需要将修改后的 numpy 数组重新分配回 python 列表,然后在常规 python 循环中迭代该列表来进行绘图。除了编写一个 C 模块来一步处理所有阅读和绘图之外,这似乎是我的最佳选择吗?


您将您的数据描述为“坐标列表列表的列表”。由此我猜你的提取看起来像这样:

for x in points:
   for y in x:
       for Z in y:
           # z is a tuple with GPS coordinates

Do this:

# initially, points is a list of lists of lists
points = itertools.chain.from_iterable(points)
# now points is an iterable producing lists
points = itertools.chain.from_iterable(points)
# now points is an iterable producing coordinates
points = itertools.chain.from_iterable(points)
# now points is an iterable producing individual floating points values
data = numpy.fromiter(points, float)
# data is a numpy array containing all the coordinates
data = data.reshape( data.size/2,2)
# data has now been reshaped to be an nx2 array

itertools 和 numpy.fromiter 都是用 C 语言实现的,而且非常高效。因此,这应该会非常快地完成转换。

您问题的第二部分并没有真正表明您想要如何处理数据。索引 numpy 数组比索引 python 列表慢。您可以通过对数据进行大量操作来提高速度。如果不了解更多关于您如何处理这些数据的信息,就很难建议如何修复它。

UPDATE:

我已经使用 itertools 和 numpy 完成了所有工作。对于因尝试理解此代码而造成的任何脑损伤,我不承担任何责任。

# firstly, we use imap to call GetMyPoints a bunch of times
objects = itertools.imap(GetMyPoints, xrange(100))
# next, we use itertools.chain to flatten it into all of the polygons
polygons = itertools.chain.from_iterable(objects)
# tee gives us two iterators over the polygons
polygons_a, polygons_b = itertools.tee(polygons)
# the lengths will be the length of each polygon
polygon_lengths = itertools.imap(len, polygons_a)
# for the actual points, we'll flatten the polygons into points
points = itertools.chain.from_iterable(polygons_b)
# then we'll flatten the points into values
values = itertools.chain.from_iterable(points)

# package all of that into a numpy array
all_points = numpy.fromiter(values, float)
# reshape the numpy array so we have two values for each coordinate
all_points = all_points.reshape(all_points.size // 2, 2)

# produce an iterator of lengths, but put a zero in front
polygon_positions = itertools.chain([0], polygon_lengths)
# produce another numpy array from this
# however, we take the cumulative sum
# so that each index will be the starting index of a polygon
polygon_positions = numpy.cumsum( numpy.fromiter(polygon_positions, int) )

# now for the transformation
# multiply the first coordinate of every point by *.5
all_points[:,0] *= .5

# now to get it out

# polygon_positions is all of the starting positions
# polygon_postions[1:] is the same, but shifted on forward,
# thus it gives us the end of each slice
# slice makes these all slice objects
slices = itertools.starmap(slice, itertools.izip(polygon_positions, polygon_positions[1:]))
# polygons produces an iterator which uses the slices to fetch
# each polygon
polygons = itertools.imap(all_points.__getitem__, slices)

# just iterate over the polygon normally
# each one will be a slice of the numpy array
for polygon in polygons:
    draw_polygon(polygon)

您可能会发现最好一次处理一个多边形。将每个多边形转换为 numpy 数组并对其进行向量运算。这样做您可能会获得显着的速度优势。将所有数据放入 numpy 可能有点困难。

由于数据形状奇特,这比大多数 numpy 的东西更困难。 Numpy 几乎假设一个数据形状统一的世界。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

numpy 数组:快速填充和提取数据 的相关文章

  • 如何循环遍历对象数组并生成键值对?

    我有一个像这样的对象数组 let someObj items id 12 value true id 34 value true id 56 value false 我想将其添加到现有对象中 其中 id 是该对象的键 如下所示 let ob
  • 合并 2 个数组并合并数字键的结果

    我有 2 个数组 我希望通过每个数字键将其中合并 分组在一起 例如 Array1 2009 gt 131 2008 gt 940 2007 gt 176 2006 gt 1 Array2 2008 gt 9 2007 gt 3 我希望输出是
  • 查找正在导入哪些 python 模块

    从应用程序中使用的特定包中查找所有 python 模块的简单方法是什么 sys modules是将模块名称映射到模块的字典 您可以检查其键以查看导入的模块 See http docs python org library sys html
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • 正在使用 PIL 保存损坏的图像

    我遇到一个问题 操作图像像素导致保存损坏的图像 因此 我使用 PIL 打开图像 然后将其转换为 NumPy 数组 image Image open myimage png np image np asarray image 然后 我转置图像
  • jQuery / Ajax:如何循环遍历数组作为 Ajax 成功函数的一部分

    我有一个阿贾克斯调用返回一个数组并需要对该数组中的每个值执行某些操作 到目前为止 我有以下内容 但这会返回以下错误 Uncaught TypeError Cannot use in operator to search for length
  • 如何用正则表达式替换多个匹配/组?

    通常我们会编写以下内容来替换一场比赛 namesRegex re compile r is life re I replaced namesRegex sub r butter There is no life in the void pr
  • 更改 Matplotlib 投影轴的背景颜色

    我正在尝试使用 Cartopy 创建一个图形 该图形需要在未投影的轴上绘制投影轴 这是一个尽可能简单的代码版本 它将轴上的内容替换为背景颜色 import matplotlib pyplot as plt import cartopy cr
  • python Recipe:列出最接近等于值的项[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 考虑像这样的列表 0 3 7 10 12 15 19 21 我想获得最接近任何值的最近的最小数字 所以如果我通过4 我会得到3 如果我
  • Seaborn 中没有线性拟合的散点图

    我想知道是否有办法关闭seaborn中的线性拟合lmplot或者是否有一个等效函数可以生成散点图 当然 我也可以使用 matplotlib 但是 我发现 seaborn 中的语法和美学非常吸引人 例如 我想绘制以下情节 import sea
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 无法导入QUERY_TERMS

    我正在运行一个网站Python and Django Django filters 2 1 installed Django 2 1 installed 当我运行时 我收到以下错误 importError Could not import
  • 从 wxPython 事件处理程序中调用函数

    我正在努力寻找一种在 wxPython 事件处理函数中使用函数的方法 假设我有一个按钮 单击该按钮时 它会使用事件处理程序运行一个名为 OnRun 的函数 但是 用户忘记单击 OnRun 按钮之前的 RadionButton 我想弹出一个
  • Python 2.7 缩进错误[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 这个问题是由拼写错误或无法再重现的问题引起的 虽然类似的问题可能是on topic help on topic在这里 这个问题的解决方式不
  • 无需访问 Internet 即可部署 Django 的简单方法?

    我拥有的是使用 Django 开发的 Intranet 站点的开发版本以及放置在 virtualenv 中的一些外部库 它运行良好 我可以在任何具有互联网连接的计算机上使用相同的参数 使用 pip 轻松设置 virtualenv 但是 不幸
  • Python 读取未格式化的直接访问 Fortran 90 给出不正确的输出

    这是数据的写入方式 它是一个二维浮点矩阵 我不确定大小 open unit 51 file rmsd nn output form unformatted access direct status replace recl Npoints
  • 没有名为“turtle”的模块

    我正在学习并尝试用Python3制作贪吃蛇游戏 我正在进口海龟 我正在使用 Linux mint 19 PyCharm python37 python3 tk Traceback most recent call last File hom
  • 两种 ODE 求解器之间的差异

    我想知道 两者之间有什么区别ODEINT and solve ivp用于求解微分方程 它们之间有什么优点和缺点 f1 solve ivp f 0 1 y0 y0 is the initial point f2 odeint f y0 0 1
  • 使用 pandas 单元格中列表的长度选择行[重复]

    这个问题在这里已经有答案了 我有一张表 df a b c 1 x y x 2 x z c d 3 x t e f g 只是想知道如何使用 c 列的长度选择行 such as df loc len df c gt 1 我知道这是不对的 正确的
  • MoviePY 无法在 Windows 上检测 ImageMagick 二进制文件

    我刚买了一台新笔记本电脑 想要设置MoviePY在那新的Windows 64x Python3 7 0 机器 我对所有内容都进行了三次检查 但是当涉及到我的代码的文本部分时 它向我抛出了这个错误 OSError MoviePy Error

随机推荐