Я использую превосходный пакет pandas
для работы с большим количеством разнообразных метеорологических диагностических данных, и мне быстро не хватает размеров, когда я собираю данные вместе. Глядя на документацию, может оказаться, что использование MultiIndex
может решить мою проблему, но я не уверен, как применить его к моей ситуации — в документации показаны примеры создания MultiIndex со случайными данными и DataFrame
s, но не Series с уже существующими данными временных рядов.
Исходная информация
Базовая структура данных, которую я использую, содержит два основных поля:
метаданные
, который представляет собой словарь, состоящий из пар ключ-значение, описывающих числаданные
, которая представляет собой структуру данных pandas, содержащую сами числа.Наименьшим общим знаменателем являются данные временных рядов, поэтому базовая структура имеет объект pandas Series
в качестве записи data
, а поле metadata
описывает, что эти числа на самом деле равны (например, среднеквадратическая ошибка вектора для 10-метрового ветра над восточной частью Тихого океана для 24-часового прогноза из эксперимента Test1).
Я собираюсь взять этот наименьший общий знаменатель и склеить различные временные ряды вместе, чтобы сделать результаты более полезными и обеспечить возможность простых комбинаций.Например, я могу захотеть посмотреть на все разные времена выполнения — у меня есть процедура фильтрации, которая будет брать мои временные ряды, которые имеют одни и те же записи метаданных , за исключением для времени выполнения (например, эксперимент, регион и т. д.). и вернуть новый объект, в котором поле метаданных состоит только из общих записей (т. е.
Время выполнения
было удалено), и теперь поле данных
представляет собой панды DataFrame
с метками столбцов, заданными значением Lead Time
. Я могу еще раз расширить это и сказать, что я хочу взять полученные кадры и сгруппировать ихвместе только с другой записью (например, Experiment
), чтобы получить панель pandas . для моей записи, где индекс элемента задается значениями метаданных
Experiment
из составляющих кадров, а новые метаданные объекта не содержат ни Lead Time
, ни Experiment
.
Когда я перебираю эти составные объекты, у меня есть процедура iterseries
для фрейма и процедура iterframes
для панели, которые реконструируют соответствующую пару метаданных/данных при удалении одного измерения. (т. е. ряд из кадра с разным временем выполнения по столбцам будет иметь все метаданные своего родителя плюс поле Время выполнения
, восстановленное со значением, взятым из метки столбца). Это прекрасно работает.
Проблема
У меня закончились размеры (вплоть до 3-D с панелью), и я также не могу использовать такие вещи, как dropna
для удаления пустых столбцов после того, как все выровнено в панели (это привело к нескольким ошибкам при построении сводной статистики). Чтение об использовании панд с многомерными данными привело к чтению о MultiIndex
и его использовании. Я пробовал примеры, приведенные в документации, но я все еще немного не понимаю, как применить это к моей ситуации. Любое направление будет полезно. Я хотел бы иметь возможность:
Series
в мультииндексированный DataFrame
по произвольному количеству измерений (это было бы здорово — было бы исключить один вызов для создания фреймов из серии, а затем другой для создания панелей из фреймов)DataFrame
, отбрасывая одно измерение, чтобы я мог сбросить компонент метаданные.Редактировать — добавить пример кода
Ответ Уэса МакКинни ниже — это почти то, что мне нужно — проблема заключается в первоначальном переводе из объектов хранения, поддерживаемых Series, с которыми мне приходится работать, в мои объекты, поддерживаемые DataFrame, когда я начинаю группировка элементов вместе. Класс с поддержкой Data-Frame имеет следующий метод, который принимает список объектов на основе серий и поля метаданных, которые будут различаться по столбцам.
@classmethod
def from_list(cls, results_list, column_key):
"""
Populate object from a list of results that all share the metadata except
for the field `column_key`.
"""
# Need two copies of the input results - one for building the object
# data and one for building the object metadata
for_data, for_metadata = itertools.tee(results_list)
self = cls()
self.column_key = column_key
self.metadata = next(for_metadata).metadata.copy()
if column_key in self.metadata:
del self.metadata[column_key]
self.data = pandas.DataFrame(dict(((transform(r[column_key]), r.data)
for r in for_data)))
return self
Когда у меня есть кадр, заданный этой подпрограммой, я могу легко применить различные операции, предложенные ниже, особенно полезным является возможность использовать поле имен
,
вызов concat
- это устраняет необходимость внутреннего хранения имени ключа столбца
так как он хранится в MultiIndex как имя этого измерения индекса.
Я хотел бы иметь возможность реализовать приведенное ниже решение и просто взять список соответствующих классов, поддерживаемых Series, и список ключей, а затем выполнить группировку последовательно. Однако,Я не знаю заранее, что столбцы будут представлять, поэтому: