在单个python对象中使多个类实例多

时间:2019-10-03 17:04:20

标签: python matlab

我处于学术背景,并且一直在使用numpy和scipy将我的一些数据分析代码库从MATLAB转换为Python 3.x(Anaconda),以便与一些无权访问的协作者合作MATLAB许可证。我还以此为借口来提高自己的python能力,而不仅仅是将其全部复制到Octave并修复所有出现的小问题。目前,我已经掌握了python的一些基本经验,但是我遇到了使用Python类复制MATLAB代码库中某些数据处理类的行为的问题。这里讨论的类基本上保存了光谱数据块以及标识符和一些基本分析。

本质上,在MATLAB中,我最终遇到了该类的Nx1实例。这使我可以通过索引父对象逐个信号地查看事物,我使用该对象将信号的所有相关数据传递给以后的分析功能。

例如:

% Sample Data
positions = [195, 250, 280];
widths = [5, 5, 10];

Data = DataObject(positions, widths)

>> Data(1)
ans = 
    DataObject with properties:
        value_a: 195
        value_b: 5

这也使我可以轻松地获取所有信号的值,从而可以轻松地将其放入电子表格或报告中。例如

>> [Data.value_a]'
ans = [195, 250, 280]

(注意:我知道在此示例中,它只是返回输入,但在实际代码中还涉及到派生的值。)

我一直在尝试找出如何在python中复制此行为,因此理想情况下,我可以执行以下操作:

positions = np.array([195, 250, 280])
widths = np.array([5, 5, 10])

Data = DataObject(positions, widths)
>>> Data[1]
<A DataObject containing only the data for the first signal>

>>> Data.value_a
array([195, 250, 280])

我尝试通过使用类似于我在MATLAB中所做的事情

for idx in range(len(centers)):
            self[idx].center = centers[idx]
__init__方法中的

,但它只是给我:

TypeError: 'SignalPeak' object is not subscriptable

大多数google结果我都能找到如何使一个对象的多个实例围绕它们放置在列表中,然后在要查看所有对象的属性时手动对其进行遍历。但是我想知道是否有一种方法可以使其行为更类似于我的原始代码,或者至少将该行为包装到类定义中。

MATLAB类定义为:

classdef DataObject
    properties
        value_a
        value_b
    end
    methods
        function obj = DataObject(reference, data)
            % reference: a Nx1 vector 
            % data: a Nx1 vector

            obj(size(reference,1),size(reference,2)) = obj; % Creates a Nx1 SignalPeak object

            % Sets the various values
            for idx = 1:length(centers(:))
                obj(idx).value_a = reference(idx)
                obj(idx).value_b = data(idx)
            end
        end    
    end
end

2 个答案:

答案 0 :(得分:0)

您可以做一些事情,但是我认为无法创建一个包装对象来包装您想要的所有数据对象的列表。这是一个这样的实现:

In [18]: class DataObject:
    ...:     def __init__(self, a, b):
    ...:         self.a = a
    ...:         self.b = b
    ...:     def __str__(self):
    ...:         return "DataObject: a={a}, b={b}".format(a=self.a, b=self.b)

In [19]: o1 = DataObject(1, 2)

In [20]: print(o1)
Out[20]: DataObject: a=1, b=2

In [21]: o2 = DataObject(3, 4)

In [22]: print(o2)
Out[22]: DataObject: a=3, b=4

In [23]: objects = DataObjects()

In [24]: objects.add(o1)

In [25]: objects.data_objects
Out[25]: [<__main__.DataObject at 0x103a0f610>]

In [26]: objects.add(o2)

In [27]: objects.data_objects
Out[27]: [<__main__.DataObject at 0x103a0f610>, <__main__.DataObject at 0x103842bd0>]

In [28]: objects.data_objects[1]
Out[28]: <__main__.DataObject at 0x103842bd0>

In [29]: objects.data_objects[1].a
Out[29]: 3

In [30]: objects.a
Out[30]: [1, 3]

我希望这会有所帮助!

答案 1 :(得分:0)

我会为此使用熊猫。

In [1]: import pandas as pd

In [2]: data = pd.DataFrame({'positions':[195, 250, 280], 'widths':[5,5,10]})

In [3]: data
Out[3]:
   positions  widths
0        195       5
1        250       5
2        280      10

获取所有信号的值非常简单:

In [4]: data.positions
Out[4]:
0    195
1    250
2    280
Name: positions, dtype: int64

您可以使用iloc获取单个信号的数据:

In [5]: data.iloc[1]
Out[5]:
positions    250
widths         5
Name: 1, dtype: int64

计算简单的派生列很容易,并且pandas具有很多函数来生成数据摘要。

In [7]: data['areas'] = data.positions * data.widths

In [8]: data
Out[8]:
   positions  widths  areas
0        195       5    975
1        250       5   1250
2        280      10   2800

剩下的就是更新分析功能以与数据框和序列一起使用。