【发布时间】:2020-11-14 03:23:07
【问题描述】:
我想做与this post 完全相同的事情,但使用二维对象数组而不是二维数字数组。
class ExchangeRate:
rate = None
name = None
otherUsefulProperty = None
def __init__(self, _rate, _name, _otherUsefulProperty):
self.rate = _rate
self.name = _name
self.otherUsefulProperty = _otherUsefulProperty
这是我对象的类。 rate 属性将是在将图合并在一起时使用的属性。
下面的代码非常适用于二维数字数组,但我无法弄清楚如何有效地使用二维对象数组来做同样的事情。请注意,性能对我正在做的事情至关重要。这是假设二维对象数组确实是高性能的。如果不是并且有更高效的方法,请告诉我。
import numpy as np
graph = np.ndarray(shape=(4, 3, 3), dtype=float, order='F')
graph[0] = [[0, 0, 1], [1, 0, 1], [2, 0, 0]]
graph[1] = [[0, 0, 1], [1, 0, 1], [2, 0, 0]]
graph[2] = [[5, 0, 0], [1, 0, 1], [2, 0, 0]]
graph[3] = [[2, 1, 0], [9, 0, 1], [0, 0, 0]]
PrintAndLog("graph of type " + str(type(graph)) + " = \n" + str(graph))
PrintAndLog("\n\n")
resultGraph = graph.max(axis=0)
PrintAndLog("resultGraph of type " + str(type(resultGraph)) + " = \n" + str(resultGraph))
输出:
graph of type <class 'numpy.ndarray'> =
[[[ 0. 0. 1.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 0. 0. 1.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 5. 0. 0.]
[ 1. 0. 1.]
[ 2. 0. 0.]]
[[ 2. 1. 0.]
[ 9. 0. 1.]
[ 0. 0. 0.]]]
resultGraph of type <class 'numpy.ndarray'> =
[[ 5. 1. 1.]
[ 9. 0. 1.]
[ 2. 0. 0.]]
可能的最终解决方案:
希望其他人觉得这很有用。我刚刚进行了大量的性能测试,并且有一个明显的赢家。
TLDR: 获胜者 = np.array + ExchangeRate object + graph.max(axis=0)。这是迄今为止我尝试过的最快的方法。再一次,目标是合并许多费率图,其中每个费率还具有与之关联的元数据,需要与之合并
这是我缩小范围的最终方法的测试结果。每个测试仅基于合并进行计时(我根据速率将多个图表合并为一个)。我记录了以下数据点:200 次运行的平均持续时间,以及第一次运行的持续时间。第一次运行很重要,因为它有时似乎比平均时间长。它可能与缓存有关。
-
test_graph_4 200 次运行平均 = 0.0003026 秒(第一次运行,~相同)
-
test_graph_3 200 次运行平均 = 0.0003836 秒(第一次运行,~相同)
-
test_graph_2b 200 次运行平均值 = 0.000018 秒(第一次运行 0.000092 秒)
-
test_graph_2a 200 次运行平均 = 0.000066 秒(第一次运行 0.000143 秒)
【问题讨论】:
-
object dtype 数组不是“高性能”。
-
与您的班级一起构建一个工作示例,并展示您已成功完成的工作,无论是否有效。如果我必须构建对象列表等来说明任何想法,那就需要更多的工作。然而,过去的答案表明,对象数组的性能类似于对象列表。编译后的代码都不会“进入”你的对象。
-
我当前的实现既不使用对象也不使用numpy。我目前只是使用 python 列表制作一个 2dlist 然后手动合并它们。我也没有使用对象,我使用单独的二维列表来表示速率、名称和 otherUsefulProperty。因此,当我合并时,我只需要暴力迭代所有这些并找到最大速率值,然后更新最终合并的 2d 列表。它的计算成本相当高。
-
我希望我可以使用 numpy 函数
graph.max(axis=0)并让它以某种方式进入我的对象。如果我不能这样做,那么也许我的蛮力合并方法是最优化的方法?为了确认,您是说您已经看到 python 列表显示出与 numpy 数组类似的性能?我还想知道我是否要保留我的蛮力合并方法,只是从 python 列表切换到 numpy 数组,如果这会给我带来任何性能提升。 -
我为此测试了各种不同的解决方案,对它们进行计时,并在上面发布了代码+结果。
标签: python pandas algorithm performance numpy