Есть ли название для этого типа структурированных данных и как его более эффективно использовать?

Я постараюсь сделать этот вопрос простым, чтобы, надеюсь, эта концепция была применима и к другим областям.

Я работаю с наборами сейсмических данных, где N землетрясений зарегистрировано M сейсмическими станциями. Существует информация о землетрясении (идентификатор землетрясения, магнитуда и т. д.) и информация о конкретной станции (идентификатор станции, частота дискретизации приборов и т. д.). Не все сейсмические станции регистрируют все землетрясения, поэтому существует разное количество станций, регистрирующих каждое землетрясение.

В настоящее время я организую эти данные в объекте Pandas DataFrame, по одной строке на каждое землетрясение. Поскольку для каждого землетрясения существует разное количество станций, я сохраняю идентификаторы станций в виде массива numpy. Вот простой пример: землетрясения 0001 и 0002 магнитудой 2,1 и 3,1 соответственно. Четыре сейсмические станции: a, b, c и d имеют частоту дискретизации 100, 100, 60 и 60 соответственно.

import numpy as np 
import pandas as pd

events = {
    'event_id': ['0001', '0002'],
    'mag': [2.1, 3.1],
    'station_ids': [np.array(['a', 'c']), np.array(['a', 'b', 'c', 'd'])],
    'station_sampling_rate': [np.array([100, 60]), np.array([100, 100, 60, 60])]
}
events = pd.DataFrame(events)
print(events)

что приводит к

  event_id  mag   station_ids station_sampling_rate
0     0001  2.1        [a, c]             [100, 60]
1     0002  3.1  [a, b, c, d]    [100, 100, 60, 60]

Теперь, когда мне нужна информация о конкретной станции из этого DataFrame, мне нужно либо:

  1. Прокрутите каждую строку events, выполните некоторую проверку и сравните с существующим каталогом станций (медленно).
  2. Сконструируйте events таким образом, чтобы он содержал все больше информации, специфичной для каждой станции (events становится действительно большим), и при этом циклично перебирал каждую строку events.

Метод 1 до сих пор работал у меня, но он медленный. Метод 2 кажется пустой тратой ресурсов.

Желаемая структура приведенного выше примера такова:

  station_id  sampling_rate     event_ids         mag
0          a            100  [0001, 0002]  [2.1, 3.1]
1          b            100        [0002]       [3.1]
2          c             60  [0001, 0002]  [2.1, 3.1]
3          d             60        [0002]       [3.1]

Существует ли эффективный способ структурировать, хранить и преобразовывать эти данные? Кажется, уже должно быть что-то, что может работать с данными такого типа.

Я пробовал искать, но не знаю, как называется эта структура данных и есть ли у нее имя.

№2, как вы описали, обычно считается стандартом, особенно если принять во внимание, как выглядит концепция нормализации в традиционных системах реляционных баз данных. Однако ваше утверждение «по-прежнему просматриваете каждую строку событий» сигнализирует о том, что вы не до конца понимаете выбранный вами инструмент (pandas). Грубо говоря, существует очень мало причин, по которым вам когда-либо придется повторять DataFrame (и если вы обнаружите, что вам нужно делать это часто, вполне вероятно, что вы выбрали совершенно неправильную структуру данных). Используйте его синтаксис правильно, например df[df['station_id'] == 'a'] для строк станции a. (1/2)

esqew 02.07.2024 00:18

Доступ к вашему DataFrame таким образом (как и предполагалось) обеспечит лучшую оптимизацию производительности, чем вы могли бы разумно ожидать от любого решения на основе циклов. Отдельно я бы не стал беспокоиться о размере events, если только у вас нет действительно веской причины для этого, поскольку pandas оптимизирован для обработки наборов данных, которые, вероятно, больше по размеру, чем ваш (хотя без дополнительной информации об этом мы можем Не могу утвердительно сказать, обоснованы ваши опасения или нет). (2/2)

esqew 02.07.2024 00:20

Также не забывайте, что приведение вашего DataFrame в более нормализованное состояние не должно быть болезненным, если вы можете использовать инструменты, которые pandas дают вам - соответствующий поток SO (3/2)

esqew 02.07.2024 00:41

Кстати, я был бы склонен назвать это «денормализованным» - поскольку нормализованное представление, скорее всего, будет состоять из нескольких таблиц (одна содержит станции, другая содержит события со столбцами Station_id, Even_id, возможно, mag). У вас должна быть возможность эффективно хранить это в parquet, поскольку он позволяет использовать поля списка или структуры (или списка структур).

David Waterworth 02.07.2024 01:44

Но я согласен с предыдущими комментариями, если только у вас не возникнут проблемы с производительностью — храните и манипулируйте как обычно. А если у вас возникнут проблемы с производительностью, вы, вероятно, сможете их исправить, используя Polars/Duckdb или другие параметры, сохраняя при этом нормализованные данные.

David Waterworth 02.07.2024 01:46

Отлично, спасибо всем. Я новичок в пандах и базах данных, но эта концепция нормализации — именно то, что я искал, но у меня не было слова.

Ian 09.07.2024 20:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Цикл по строкам в Pandas по своей сути очень медленный и (почти) никогда не нужен. Для приведенного примера:

events2 = events.explode(['station_ids', 'station_sampling_rate'])

results = events2.groupby(['station_ids', 'station_sampling_rate'], as_index = False)[['mag', 'event_id']].agg(list)

print(results)

дает DF:

  station_ids station_sampling_rate         mag      event_id
0           a                   100  [2.1, 3.1]  [0001, 0002]
1           b                   100       [3.1]        [0002]
2           c                    60  [2.1, 3.1]  [0001, 0002]
3           d                    60       [3.1]        [0002]

Работает отлично, спасибо.

Ian 09.07.2024 20:27

Другие вопросы по теме