连接作为 python 中类实例属性的 numpy 数组

发布于 2025-01-04 05:36:23 字数 1490 浏览 0 评论 0原文

我正在尝试使用一个类,该类将另一个类的多个实例串在一起作为对象的 numpy 数组。我希望能够连接 numpy 数组中包含的实例的属性。我想出了一种用一堆 for 循环的草率方法来做到这一点,但我认为必须有一种更优雅、Pythonic 的方法来做到这一点。以下代码执行我想要的操作,但我想知道是否有更简洁的方法来执行此操作:

import numpy as np


class MyClass(object):

    def __init__(self):
        self.a = 37.
        self.arr = np.arange(5)


class MyClasses(object):

    def __init__(self):
        self.N = 5 
        # number of MyClass instances to become attributes of this
    # class 

    def make_subclas_arrays(self):
        self.my_class_inst = np.empty(shape=self.N, dtype="object") 
        for i in range(self.N):
            self.my_class_inst[i] = MyClass()

    def concatenate_attributes(self):
        self.a = np.zeros(self.N)
        self.arr = np.zeros(self.N * self.my_class_inst[0].arr.size)
        for i in range(self.N):
            self.a[i] = self.my_class_inst[i].a
            slice_start = i * self.my_class_inst[i].arr.size
            slice_end = (i + 1.) * self.my_class_inst[i].arr.size
            self.arr[slice_start:slice_end] = ( 
        self.my_class_inst[i].arr )

my_inst = MyClasses()
my_inst.make_subclas_arrays()
my_inst.concatenate_attributes()

编辑:根据 HYRY 的响应,这些方法现在如下所示:

def make_subclass_arrays(self):
    self.my_class_inst = np.array([MyClass() for i in range(self.N)])

def concatenate_attributes(self):
    self.a = np.hstack([i.a for i in self.my_class_inst])
    self.arr = np.hstack([i.arr for i in self.my_class_inst])

I am attempting to use a class that strings together several instances of another class as a numpy array of objects. I want to be able to concatenate attributes of the instances that are contained in the numpy array. I figured out a sloppy way to do it with a bunch of for loops, but I think there must be a more elegant, pythonic way of doing this. The following code does what I want, but I want to know if there is a cleaner way to do it:

import numpy as np


class MyClass(object):

    def __init__(self):
        self.a = 37.
        self.arr = np.arange(5)


class MyClasses(object):

    def __init__(self):
        self.N = 5 
        # number of MyClass instances to become attributes of this
    # class 

    def make_subclas_arrays(self):
        self.my_class_inst = np.empty(shape=self.N, dtype="object") 
        for i in range(self.N):
            self.my_class_inst[i] = MyClass()

    def concatenate_attributes(self):
        self.a = np.zeros(self.N)
        self.arr = np.zeros(self.N * self.my_class_inst[0].arr.size)
        for i in range(self.N):
            self.a[i] = self.my_class_inst[i].a
            slice_start = i * self.my_class_inst[i].arr.size
            slice_end = (i + 1.) * self.my_class_inst[i].arr.size
            self.arr[slice_start:slice_end] = ( 
        self.my_class_inst[i].arr )

my_inst = MyClasses()
my_inst.make_subclas_arrays()
my_inst.concatenate_attributes()

Edit: Based on the response from HYRY, here is what the methods look like now:

def make_subclass_arrays(self):
    self.my_class_inst = np.array([MyClass() for i in range(self.N)])

def concatenate_attributes(self):
    self.a = np.hstack([i.a for i in self.my_class_inst])
    self.arr = np.hstack([i.arr for i in self.my_class_inst])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦回旧景 2025-01-11 05:36:23

您可以使用 numpy.hstack() 来连接数组:

def concatenate_attributes(self):
    self.a = np.hstack([o.a for o in self.my_class_inst])
    self.arr = np.hstack([o.arr for o in self.my_class_inst])

另请参阅

vstack :垂直(按行)顺序堆叠数组。
dstack :按深度顺序(沿第三轴)堆叠数组。
concatenate :将一系列数组连接在一起。

you can use numpy.hstack() to concatenate arrays:

def concatenate_attributes(self):
    self.a = np.hstack([o.a for o in self.my_class_inst])
    self.arr = np.hstack([o.arr for o in self.my_class_inst])

See Also

vstack : Stack arrays in sequence vertically (row wise).
dstack : Stack arrays in sequence depth wise (along third axis).
concatenate : Join a sequence of arrays together.

是伱的 2025-01-11 05:36:23

对于后一个函数,我建议这样做:

init = []
ContainerClass.arr = np.array([init + Array(myclass.arr) for myclass in self.my_class_inst])

将 numpy 数组类型转换为普通数组,将其连接并类型转换回来。假设现在您有简单的一维数组。我不记得 numpy 数组是否有连接函数。您可以使用它来代替“+”号,从而省去打字的麻烦。

对于第一个,你有我能想到的最简单的形式,尽管我通常使用普通数组而不是 numpy 数组作为对象。

如果你想变得更聪明,你可以为这两个类创建一个 __add__ 函数。然后你可以使用“+”号来添加类。 a + b 调用 a.__add__(b)。现在,您必须创建具有以下属性的函数

  1. MyClass + MyClass 返回新的 MyClasses 实例,其中
  2. MyClasses 中包含 a 和 b + MyClass 以您想要的方式将 MyClass 添加到 MyClasses

现在,如果 a、b、c、d 是 myClass 实例,a+b+c+d 应该返回 MyClasses -class,其中包含 MyClass 实例 a、b、c 和 d 及其组合数组。这将是Pythonic的方式,尽管它对我来说有点太复杂了。

编辑:

好吧,抱歉我的错。我写代码的时候没有python。这是正确的版本:

init = []
my_inst.arr = np.array([init + list(myclass.arr.flat) for myclass in my_inst.my_class_inst]).flatten()

这就是我对 __add__ 的意思(以及 pythonic 方式......不管它的复杂性):

import numpy as np

class MyClass(object):

    def __init__(self):
        self.a = 37.
        self.arr = np.arange(5)

    def __add__(self, classToAdd):
        a = MyClasses() + self + classToAdd
        return a


class MyClasses(object):

    def __init__(self):
        self.N = 0
        self.my_class_inst = np.array([])
        self.a = np.array([])
        self.arr = np.array([])

    def __add__(self, singleClass):
        self.my_class_inst = np.hstack([self.my_class_inst, singleClass])
        self.a = np.hstack([self.a, singleClass.a])
        self.arr = np.hstack([self.arr, singleClass.arr])
        self.N = self.my_class_inst.shape[0]
        return self

#add_test = MyClass() + MyClass()
add_test = np.sum([MyClass() for i in range(5)])

print add_test.a, add_test.arr, add_test.N
print add_test.__class__, add_test.my_class_inst[0].__class__

For the latter function I would recommend this:

init = []
ContainerClass.arr = np.array([init + Array(myclass.arr) for myclass in self.my_class_inst])

typecast numpy array to normal array, catenate and typecast it back. Assuming now that you have simple 1D arrays. I don't remember by heart if numpy array has catenation function. You can use that instead of '+' sign and save the trouble of typecasting.

For the first you have the simplest form I can think of, although I usually use normal arrays instead of numpy ones for objects.

If you want to be really clever you can create an __add__ function for both of the classes. Then you can use '+' sign to add classes. a + b calls a.__add__(b). Now you would have to create functions that have following properties

  1. MyClass + MyClass returns new MyClasses instance with a and b inside
  2. MyClasses + MyClass adds MyClass to MyClasses in a way you want

Now if a,b,c,d are myClass instances, a+b+c+d should return MyClasses -class which contains MyClass instances a,b,c and d and their combined arrays. This would be the pythonic way, although its a bit too complicated in my taste.

edit:

Ok, sorry my bad. I did not have python when I wrote the code. This is the correct version:

init = []
my_inst.arr = np.array([init + list(myclass.arr.flat) for myclass in my_inst.my_class_inst]).flatten()

This is what I meant with the __add__ (and the pythonic way... regadless of its complicatedness):

import numpy as np

class MyClass(object):

    def __init__(self):
        self.a = 37.
        self.arr = np.arange(5)

    def __add__(self, classToAdd):
        a = MyClasses() + self + classToAdd
        return a


class MyClasses(object):

    def __init__(self):
        self.N = 0
        self.my_class_inst = np.array([])
        self.a = np.array([])
        self.arr = np.array([])

    def __add__(self, singleClass):
        self.my_class_inst = np.hstack([self.my_class_inst, singleClass])
        self.a = np.hstack([self.a, singleClass.a])
        self.arr = np.hstack([self.arr, singleClass.arr])
        self.N = self.my_class_inst.shape[0]
        return self

#add_test = MyClass() + MyClass()
add_test = np.sum([MyClass() for i in range(5)])

print add_test.a, add_test.arr, add_test.N
print add_test.__class__, add_test.my_class_inst[0].__class__
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文