Другое

Преобразование списка словарей в DataFrame Pandas

Узнайте самый эффективный способ преобразования списка словарей с несогласованными ключами в DataFrame Pandas. Автоматическое заполнение NaN для отсутствующих ключей с помощью простого конструктора pd.DataFrame().

Как я могу преобразовать список словарей в pandas DataFrame в Python? У меня есть список словарей с несогласованными ключами, и я хочу создать DataFrame, где отсутствующие значения будут заполнены NaN. Например, как преобразовать:

python
[{'points': 50, 'time': '5:00', 'year': 2010}, 
 {'points': 25, 'time': '6:00', 'month': "february"}, 
 {'points':90, 'time': '9:00', 'month': 'january'}, 
 {'points_h1':20, 'month': 'june'}]

в:

      month  points  points_h1  time  year
0       NaN      50        NaN  5:00  2010
1  february      25        NaN  6:00   NaN
2   january      90        NaN  9:00   NaN
3      june     NaN         20   NaN   NaN

Какой самый эффективный способ обработки словарей с разными ключами при создании pandas DataFrame?

При преобразовании списка словарей с несогласованными ключами в DataFrame pandas можно просто использовать конструктор pd.DataFrame(), который автоматически обрабатывает отсутствующие ключи, заполняя их значениями NaN. Этот метод является как эффективным, так и простым, поскольку pandas умело определяет все уникальные ключи из ваших словарей и создает соответствующие столбцы, помещая NaN там, где ключи отсутствуют в отдельных словарях.

Содержание

Базовый метод преобразования

Самый простой и эффективный способ преобразования списка словарей в DataFrame pandas - использование конструктора pd.DataFrame(). Этот метод автоматически определяет все уникальные ключи в ваших словарях и создает соответствующие столбцы, заполняя отсутствующие значениями NaN.

python
import pandas as pd

data = [{'points': 50, 'time': '5:00', 'year': 2010}, 
        {'points': 25, 'time': '6:00', 'month': "february"}, 
        {'points':90, 'time': '9:00', 'month': 'january'}, 
        {'points_h1':20, 'month': 'june'}]

df = pd.DataFrame(data)
print(df)

Это дает именно желаемый результат:

      month  points  points_h1  time  year
0       NaN      50        NaN  5:00  2010
1  february      25        NaN  6:00   NaN
2   january      90        NaN  9:00   NaN
3      june     NaN         20   NaN   NaN

Как объясняет datagy: “Любой словарь, у которого отсутствует ключ, вернет отсутствующее значение, NaN” - это поведение по умолчанию, которое делает это преобразование таким удобным.


Обработка несогласованных ключей

При работе с несогласованными ключами в словарях pandas предоставляет несколько стратегий для эффективной обработки отсутствующих значений:

Автоматическое заполнение NaN

Конструктор pd.DataFrame() автоматически заполняет отсутствующие значениями NaN, что именно то, что вам нужно для вашего случая использования. Spark By Examples подтверждает это: “Pandas вставит NaN для отсутствующих значений в этих столбцах”.

Управление порядком столбцов

Вы можете управлять порядком столбцов и даже добавлять столбцы, которые отсутствуют в любом из словарей, указав параметр columns:

python
# Управление порядком столбцов и добавление несуществующего столбца
df = pd.DataFrame(data, columns=['month', 'points', 'points_h1', 'time', 'year', 'nonexistent'])

Это обеспечивает согласованную структуру, даже если ваши словари имеют разные ключи. Как демонстрирует thisPointer: “Если мы предоставляем список столбцов в качестве аргумента конструктору DataFrame… этот столбец в DataFrame будет содержать только значения NaN”.

Согласованность типов

Имейте в виду, что когда некоторые словари не содержат ключей, pandas может преобразовывать целочисленные типы в float для accommodate значений NaN. Об этом упоминается в обсуждении Stack Overflow: “Это ‘портит’ dtypes и преобразует целые числа в float”.


Альтернативные методы преобразования

Хотя pd.DataFrame() является самым прямым подходом, pandas предлагает несколько альтернативных методов для преобразования списков словарей:

DataFrame.from_dict()

Этот метод полезен, когда у вас есть словарь словарей, а не список:

python
dict_data = {
    'row1': {'points': 50, 'time': '5:00', 'year': 2010},
    'row2': {'points': 25, 'time': '6:00', 'month': "february"}
}
df = pd.DataFrame.from_dict(dict_data, orient='index')

Однако, согласно обсуждениям проблем на GitHub, from_dict() может быть значительно медленнее, чем базовый конструктор, особенно при работе с большими наборами данных.

DataFrame.from_records()

Этот метод оптимизирован для преобразования структурированных записей и может быть более эффективным для определенных структур данных:

python
df = pd.DataFrame.from_records(data)

json_normalize()

Для вложенных структур словарей json_normalize() предоставляет мощные возможности нормализации:

python
from pandas import json_normalize
df = json_normalize(data)

Как отмечает sqlpey: “Все pd.DataFrame(), pd.DataFrame.from_dict() и pd.DataFrame.from_records() элегантно обрабатывают списки словарей с разными ключами, заполняя отсутствующие значениями NaN”.


Сравнение производительности

При работе с большими наборами данных производительность становится критически важным фактором:

Самый эффективный метод

Конструктор pd.DataFrame() обычно является самым эффективным методом для преобразования списков словарей. Согласно многочисленным обсуждениям на Stack Overflow и проблемам на GitHub, базовый конструктор значительно превосходит альтернативы.

Проблемы производительности с from_dict()

У метода from_dict() известны ограничения производительности:

  • Может занимать 2.5-3 минуты для 200 000 строк и 6 000 столбцов
  • Еще медленнее (7+ минут) со структурами MultiIndex
  • Значительно менее эффективен, чем базовый конструктор

Производительность from_records()

from_records() может быть более эффективным, чем from_dict(), но все еще может уступать базовому конструктору pd.DataFrame() для определенных паттернов данных.

Важные замечания по памяти

Для очень больших наборов данных рассмотрите возможность обработки порциями или использования более эффективных с точки зрения памяти структур данных перед преобразованием в pandas.


Продвинутые техники

Предварительная обработка словарей

Если вам нужен больший контроль над процессом преобразования, вы можете предварительно обработать ваши словари:

python
# Найти все уникальные ключи
all_keys = set()
for d in data:
    all_keys.update(d.keys())
all_keys = sorted(all_keys)

# Нормализовать словари для наличия всех ключей
normalized_data = []
for d in data:
    normalized_d = {key: d.get(key) for key in all_keys}
    normalized_data.append(normalized_d)

df = pd.DataFrame(normalized_data)

Пользовательская обработка отсутствующих значений

Вы можете настроить, как обрабатываются отсутствующие значения, используя fillna() после преобразования:

python
df = pd.DataFrame(data)
df = df.fillna('missing')  # Заменить NaN на 'missing'

Преобразование типов

После обработки отсутствующих значений вы можете преобразовать типы данных соответствующим образом:

python
df = pd.DataFrame(data)
df['points'] = pd.to_numeric(df['points'], errors='coerce')

Практические примеры

Пример 1: Базовое преобразование с вашими данными

python
import pandas as pd

data = [{'points': 50, 'time': '5:00', 'year': 2010}, 
        {'points': 25, 'time': '6:00', 'month': "february"}, 
        {'points':90, 'time': '9:00', 'month': 'january'}, 
        {'points_h1':20, 'month': 'june'}]

# Простое преобразование - автоматически обрабатывает отсутствующие ключи
df = pd.DataFrame(data)
print(df)

Пример 2: Управление порядком столбцов

python
# Указать желаемый порядок столбцов
df = pd.DataFrame(data, columns=['month', 'points', 'points_h1', 'time', 'year'])
print(df)

Пример 3: Обработка разных типов данных

python
# Преобразование числовых столбцов и обработка дат
df = pd.DataFrame(data)
df['points'] = pd.to_numeric(df['points'], errors='coerce')
df['year'] = pd.to_numeric(df['year'], errors='coerce')
df['time'] = pd.to_datetime(df['time'], format='%H:%M', errors='coerce')
print(df)

Пример 4: Обработка больших наборов данных

python
# Для больших наборов данных рассмотрите обработку порциями
large_data = [{'points': i, 'time': f'{i%24}:00'} for i in range(100000)]
# Обрабатывать порциями при необходимости
df = pd.DataFrame(large_data)

Заключение

Преобразование списка словарей с несогласованными ключами в DataFrame pandas является простым с использованием конструктора pd.DataFrame(), который автоматически заполняет отсутствующие значениями NaN. Вот основные выводы:

  1. Используйте pd.DataFrame() для самого простого и эффективного преобразования - он автоматически обрабатывает несогласованные ключи, заполняя отсутствующие значениями NaN.

  2. Управляйте структурой столбцов с помощью параметра columns для указания точного порядка столбцов и обеспечения согласованности.

  3. Имейте в виду изменения типов данных при наличии отсутствующих значений, поскольку pandas может преобразовывать целые числа в float для accommodate значений NaN.

  4. Учитывайте производительность при работе с большими наборами данных - базовый конструктор обычно быстрее, чем альтернативы, такие как from_dict().

  5. Предварительно обрабатывайте данные, если вам нужен больший контроль над процессом преобразования или вы хотите реализовать пользовательскую обработку отсутствующих значений.

В большинстве случаев простой подход pd.DataFrame(data) эффективно и полноценно удовлетворит ваши потребности, создавая именно тот тип DataFrame, который вы ищете, с согласованными столбцами и значениями NaN для отсутствующих ключей.

Источники

  1. Преобразование списка словарей в DataFrame pandas - Spark By Examples
  2. Преобразование списка словарей в DataFrame pandas: Всеобъемлющее руководство | Saturn Cloud Blog
  3. Преобразование списка словарей в DataFrame pandas - Stack Overflow
  4. Список словарей Python в DataFrame pandas – Будьте на правильной стороне изменений
  5. Преобразование списка словарей в DataFrame pandas • datagy
  6. Pandas: Создание DataFrame из списка словарей - thisPointer
  7. Преобразование списка словарей в DataFrame pandas: Методы и лучшие практики
  8. pandas: Преобразование списка словарей в DataFrame с помощью json_normalize | note.nkmk.me
  9. Проблемы производительности DataFrame.from_dict() • Проблема #20488 • pandas-dev/pandas
  10. Плохая производительность Pandas DataFrame.from_dict() при генерации из длинного словаря словарей - Stack Overflow
Авторы
Проверено модерацией
Модерация