Numpy如何实现对象数组?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我试图用Python实现一个格子模型的模拟。每个点阵都有许多属性,并按照一定的规则与相邻的点阵相互作用。我认为,使用所有属性创建一个类并对该类的实例进行网格化可能是明智的。

这是我的代码:

class site:
    def __init__(self,a,...):
        self.a = a
        .... other properties ...
    def set_a(self, new_a):
        self.a = new_a

现在我想要处理这样的站点的2D/3D网格(网格),所以我尝试这样做(这里是一个2D3x3网格,但在仿真中我需要的顺序是>1000x1000X1000)

lattice = np.empty( (3,3), dtype=object)
lattice[:,:] = site(3)

现在的问题是,每个格点都引用同一个实例,例如

lattice[0,0].set_a(5)

也将设置格的值。0,2.A至5。这种行为是多余的。

for i in range(3):
    for j in range(3):
        lattice[i,j] = site(a)

但是,是否有更好的方法(不涉及循环)将对象分配给多维数组?

提问于
用户回答回答于

vectorize:class's__init__function:

import numpy as np

class Site:
    def __init__(self, a):
        self.a = a
    def set_a(self, new_a):
        self.a = new_a

vSite = np.vectorize(Site)

init_arry = np.arange(9).reshape((3,3))

lattice = np.empty((3,3), dtype=object)
lattice[:,:] = vSite(init_arry)

用户回答回答于

对于您来说,缺少的部分是Python将所有东西都视为引用。

lattice[:,:] = site(3)

你说的是“Python:创建一个新的对象”site,告诉每一个元素lattice指向那个物体。“。要了解这一点,请打印数组以查看对象的内存地址都是相同的:

array([[<__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>],
       [<__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>],
       [<__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>,
        <__main__.Site object at 0x1029d5610>]], dtype=object)

循环方式是一种正确的方法。对于numpy数组,这可能是最好的选择;对于Python列表,还可以使用列表理解:

lattice = [ [Site(i + j) for i in range(3)] for j in range(3) ]

您可以使用列表理解与numpy.array

lattice = np.array( [ [Site(i + j) for i in range(3)] for j in range(3) ],
                    dtype=object)

现在当你打印lattice,它是

array([[<__main__.Site object at 0x1029d53d0>,
        <__main__.Site object at 0x1029d50d0>,
        <__main__.Site object at 0x1029d5390>],
       [<__main__.Site object at 0x1029d5750>,
        <__main__.Site object at 0x1029d57d0>,
        <__main__.Site object at 0x1029d5990>],
       [<__main__.Site object at 0x1029d59d0>,
        <__main__.Site object at 0x1029d5a10>,
        <__main__.Site object at 0x1029d5a50>]], dtype=object)

所以你可以看到里面的每一个物体都是独一无二的。

还请注意,Python类使用CamelCase而不是小写编写是标准的。

扫码关注云+社区