Mutltiple несколько экземпляров класса в одном объекте Python - PullRequest
0 голосов
/ 03 октября 2019

Я нахожусь в академической среде и работаю над переводом части моей базы кода анализа данных из MATLAB в Python 3.x (Anaconda), используя numpy и scipy, чтобы работать с некоторыми сотрудниками, у которых нет доступаЛицензия MATLAB. Я также использую это в качестве предлога для улучшения своих возможностей на Python вместо того, чтобы просто копировать все это в Octave и исправлять любые небольшие проблемы, которые возникают. На данный момент у меня есть некоторый базовый опыт работы с python, но у меня возникают проблемы с репликацией поведения некоторых классов обработки данных в моей базе кода MATLAB с классами Python. Рассматриваемый класс в основном содержит куски спектральных данных вместе с идентификатором и некоторым базовым анализом.

По сути, в 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]

(Примечание: я знаю, что в этом примере это просто возврат ввода, но есть и производные значения, которые меня интересуют в реальном коде.)

I 'мы пытались выяснить, как повторить это поведение в 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 голосов
/ 03 октября 2019

Я бы использовал для этого панд.

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

Все, что осталось бы, этообновление ваших функций анализа для работы с фреймами данных и сериями.

0 голосов
/ 03 октября 2019

Есть несколько вещей, которые вы можете сделать, но я думаю, что нет никакого способа создать объект-обертку, который обернет список всех объектов данных, которые вы хотели бы. Вот одна из таких реализаций:

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]

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...