【问题标题】:How to pythonically pass numpy.array to method of objects in numpy.array如何以 python 方式将 numpy.array 传递给 numpy.array 中的对象方法
【发布时间】:2019-08-16 22:25:29
【问题描述】:

我有一个 2d numpy 数组 txtStrs 包含我作为文本写入 matplotlib 图形轴 ax 的字符串,例如

ax.text( posX, posY, txtStrs[0,0] )

稍后,我想更新这些文本(相同的位置、颜色等)而不重绘整个图形。因此,我将文本对象保存到另一个 numpy 数组中。

当我现在想更新文本时,我使用了两个 for 循环

    import numpy as np
    import matplotlib.pyplot as plt
    siz = 20

    txtStrs = np.empty( (siz, siz), dtype = str )
    txtObjs = np.empty( (siz, siz), dtype = object )

    plt.figure()
    ax = plt.gca()
    for x in range(siz):
        for y in range(siz)):
            txtObjs[x,y] = ax.text( x, y, "" )

    #Fill txtStrs with some string values

    for x in range(siz):
        for y in range(siz)):
            txtObjs[x,y].set_text( txtStrs[x,y] )

最后一个 for 循环对我来说似乎是不必要的,也不是真正的 Pythonic。如果我不需要调用 set_text 方法,我可以使用 numpy 的内在理解来进行更新。

我的问题是:还有其他方法可以将txtStrs 传递给txtObjs,例如使用矢量化、列表理解或其他方法?

【问题讨论】:

  • 你为什么要使用numpy.ndarray对象?
  • 小心dtype=str,相当于U1,一个字符串!
  • 当您创建text(带有ax.text)时,ax 会将其附加到自己的.texts 列表中。我不建议直接使用它,但它证明你不应该回避在列表(或列表列表)中保留自己的 text 对象(和字符串)。
  • @hpaulj 你的意思是列表而不是二维数组?我希望有一些智能编译的 numpy 功能......(我在这里使用 dtype=str 只是为了缩短 sn-p)

标签: python numpy matplotlib iteration


【解决方案1】:

循环是 Pythonic 的!

并且使用matplotlib.text 对象的set_text 方法也是有效的Python。这就是我们使用对象的方式——使用它们的方法。

使用numpy,我们尽量避免循环,但如果数组包含数字(或字符串)dtypes,那只会显着节省时间。然后它可以使用提供的数组方法在编译代码中进行迭代。您的 txtObjs 数组是 object dtype,并且对此类数组的大多数操作都涉及 Python 级别的迭代,即使它是隐藏的。像列表一样,对象数组包含指向内存中其他位置的对象的指针。它必须引用每个对象并使用自己的方法。

对象数组的迭代比列表的迭代慢一点,尽管数组的多维特性可以使迭代更漂亮。

列表推导式是编写 for 循环的一种巧妙方法 - 如果您要返回一个新列表。它不适用于就地修改。一些“矢量化”(隐藏)迭代的 numpy 函数也是如此。

如果txtObjstxtStrs 是大小相同的列表,那么

for a, b in zip(txtObjs, txtStrs):
    a.set_text(b)

应该更新所有text 对象。

对于二维数组:

for a, b in zip(txtObjs.ravel(), txtStrs.ravel()):

应该也可以。这些数组的二维形状妨碍了简单地传输值,尽管设置初始坐标可能很方便。

【讨论】:

    【解决方案2】:

    这里有一些东西可以将这两个循环减少到只有一个,但我真的不认为有“apply”、“forEach”或类似的东西。

    for (x, y), text_obj in np.ndenumerate(txtObjs):
        text_obj.set_text(txtStrs[x, y])
    

    这使用了ndenumerate,这是一种遍历 n 维 numpy 数组的巧妙方法。

    【讨论】:

    • 感谢您指出ndenumerate,我不知道这一点,我喜欢代码的可读性。在我的用例中,我负责将两个数组完全一对一地结构化,这就是我切换到 ravel-and-zip 解决方案的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 2013-10-12
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多