Извините, я знаю, что заголовок несколько нечеткий.
Контекст
Я использую Dataframe
для отслеживания файлов, потому что pandas DataFrame
содержит несколько соответствующие функции для выполнения всех видов фильтрации, которые не могут выполнять dict, с loc
, pd.IndexSlice
, .index
, .columns
, pd.MultiIndex
... Хорошо, так что это может показаться не лучшим выбором для опытных разработчиков (чего я не являюсь), но все эти функции были настолько удобны, что я использовал для этого DataFrame
. И вишенка на торте, __repr__
из MultiIndex Dataframe
просто идеально подходит, когда я хочу знать, что находится внутри моего списка файлов.
Краткое введение в класс Summary
, наследующий от DataFrame
Поскольку мой DataFrame
, который я называю «Сводка», имеет некоторые специфические c функции, я хотел бы сделать его классом, унаследованным от pandas DataFrame
класса. Он также имеет «фиксированные» MultiIndexes для строк и столбцов.
Наконец, поскольку мой класс Summary
определен вне класса Store
, который фактически управляет файловой организацией, классу Summary
нужна функция из Store
, чтобы иметь возможность получить организацию файлов.
Вопросы
Проблема с pd.DataFrame
(AFAIK): вы не можете добавлять строки без создания нового DataFrame
. Поскольку Summary
имеет функцию refresh
, так что он может recreate
сам читать содержимое папки, refresh
каким-то образом «сбрасывает» объект «Сводка». Чтобы управлять Summary
refre sh, я придумал первый код (не работает) и, наконец, второй (рабочий).
import pandas as pd
import numpy as np
# Dummy function
def summa(a,b):
return a+b
# Does not work
class DatF1(pd.DataFrame):
def __init__(self,meth,data=None):
cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
names=['Component','Interval'])
super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
self.meth=meth
def refresh(self):
values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
[pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
rmidx = pd.MultiIndex.from_arrays([['Comp1','Comp1'],['1h','1W']],names=['Component','Interval'])
self = pd.DataFrame(values, index=rmidx, columns=self.columns)
ex1 = DatF1(summa)
In [10]: ex1.meth(3,4)
Out[10]: 7
ex1.refresh()
In [11]: ex1
Out[11]: Empty DatF1
Columns: [(Index, First), (Index, Last)]
Index: []
После refresh()
, ex1
все еще пусто. refresh
работает некорректно.
# Works
class DatF2(pd.DataFrame):
def __init__(self,meth,data=None):
cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
names=['Component','Interval'])
super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
self.meth=meth
def refresh(self):
values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
[pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
rmidx = pd.MultiIndex.from_arrays([['Comp1','Comp1'],['1h','1W']],names=['Component','Interval'])
super().__init__(values, index=rmidx, columns=self.columns)
ex2 = DatF2(summa)
In [10]: ex2.meth(3,4)
Out[10]: 7
ex2.refresh()
In [11]: ex2
Out[11]: Index
First Last
Component Interval
Comp1 1h 2020-02-10 08:00:00 2020-02-10 08:00:00
1W 2020-02-11 08:00:00 2020-02-12 08:00:00
Этот код работает!
У меня 2 вопроса:
почему 1-й код не работает? (Извините, это может быть очевидно, но я совершенно не понимаю, почему это не работает)
вызывает super().__init__
в моем методе refresh
приемлемая практика кодирования? (или перефразируя иначе: допустимо ли набирать super().__init__
в других местах, кроме __init__
моего подкласса?)
Большое спасибо за вашу помощь и совет. Мир наследования классов для меня совершенно новый, и тот факт, что содержимое DataFrame
не может быть изменено напрямую, так сказать, мне кажется, делает его более сложным для обработки.
Хорошего day, Bests,
Сообщение об ошибке при добавлении новой строки
import pandas as pd
import numpy as np
# Dummy function
def new_rows():
return [['Comp1','Comp1'],['1h','1W']]
# Does not work
class DatF1(pd.DataFrame):
def __init__(self,meth,data=None):
cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
names=['Component','Interval'])
super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
self.meth=meth
def refresh(self):
values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
[pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
rmidx = self.meth()
self[rmidx] = values
ex1 = DatF1(new_rows)
ex1.refresh()
KeyError: "None of [MultiIndex([('Comp1', 'Comp1'),\n ( '1h', '1W')],\n names=['Component', 'Interval'])] are in the [index]"