Рубрики
Без рубрики

Обзор инструментов ввода / вывода в пандах

У Pands есть много функциональности, но прежде чем вы сможете исследовать или использовать его, вы, скорее всего, захотите … Теги с Python, Pandas.

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

В этом посте я собираюсь сделать быстрый обзор некоторых основных ввода/вывода для основных вариантов, которые поддерживают Pandas. Все это доступно в документации, но вместо того, чтобы сосредоточиться на деталях здесь, я хочу получить набор данных реального мира и перейти на базовый код, необходимый для записи этого набора данных, а затем прочитать его обратно с теми же значениями, а типы, представленные в набор. Это даст нам базовый обзор всех API.

Для набора входных данных я буду использовать Yahoo! Финансы API схватить некоторые исторические данные фондового рынка. Это позволит нам увидеть обработку типов данных, таких как строки, даты и числовые значения.

Все эти примеры были впервые написаны и протестированы с Python 3.8.6 и Pandas 1.1.4, используя отдельный VirtualenV, созданный с использованием пинв .

Во-первых, давайте установим наши зависимости, используя PIP (при необходимости запустите эту ячейку). Если вы используете AnaConda, вам может потребоваться установить некоторые из них отдельно в зависимости от того, как вы устанавливаете свою среду.

Для каждого из параметров ввода/вывода ниже я объясню, какие из этих установок необходимо, чтобы вы могли просто установить тех, которые вам нужны.

# in ipython or jupyter
%pip install yfinance pandas jupyter matplotlib openpyxl xlrd tables pyarrow
# command line
$ pip install yfinance pandas jupyter matplotlib openpyxl xlrd tables pyarrow 

Итак, давайте пойдем вперед и сначала возьму наши данные.

import os

import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt

msft = yf.Ticker('MSFT')

prices = msft.history(period='max')

Если вы следуете за интерактивным сеансом, вы сможете увидеть, какие цены Dataframe похоже.

>>> prices.head()
                Open High Low Close Volume Dividends Stock Splits
Date
1986-03-13 0.056367 0.064656 0.056367 0.061893 1031788800 0.0 0.0
1986-03-14 0.061893 0.065209 0.061893 0.064103 308160000 0.0 0.0
1986-03-17 0.064103 0.065761 0.064103 0.065209 133171200 0.0 0.0
1986-03-18 0.065209 0.065761 0.062998 0.063551 67766400 0.0 0.0
1986-03-19 0.063551 0.064103 0.061893 0.062446 47894400 0.0 0.0
>>> prices.shape
(8757, 7)
>>> prices.describe()
              Open High Low Close Volume Dividends Stock Splits
count 8757.000000 8757.000000 8757.000000 8757.000000 8.757000e+03 8757.000000 8757.000000
mean 27.605228 27.898439 27.304389 27.611278 5.988022e+07 0.002251 0.001941
std 38.664189 39.066306 38.232989 38.672286 3.865088e+07 0.041333 0.060893
min 0.056367 0.058577 0.056367 0.057472 2.304000e+06 0.000000 0.000000
25% 2.392274 2.422115 2.367407 2.382327 3.601770e+07 0.000000 0.000000
50% 18.598666 18.802277 18.407415 18.580099 5.303360e+07 0.000000 0.000000
75% 26.421556 26.742760 26.166867 26.399563 7.366680e+07 0.000000 0.000000
max 228.671335 232.251952 226.756345 231.045105 1.031789e+09 3.080000 2.000000
>>> prices.index
DatetimeIndex(['1986-03-13', '1986-03-14', '1986-03-17', '1986-03-18',
               '1986-03-19', '1986-03-20', '1986-03-21', '1986-03-24',
               '1986-03-25', '1986-03-26',
               ...
               '2020-11-23', '2020-11-24', '2020-11-25', '2020-11-27',
               '2020-11-30', '2020-12-01', '2020-12-02', '2020-12-03',
               '2020-12-04', '2020-12-07'],
              dtype='datetime64[ns]', name='Date', length=8757, freq=None)
>>> prices.dtypes
Open float64
High float64
Low float64
Close float64
Volume int64
Dividends float64
Stock Splits float64
dtype: object

Наши данные

Теперь у нас есть панда Dataframe С индексом даты, значениями плавающих точек для открытых, высоких, низких, близких, дивидендов и запасов. Объем – это целочисленный тип. Это позволит нам исследовать некоторые основы для того, чтобы сохранять и читать данные в различных форматах, доступных нам в пандах.

В этом посте мы посмотрим на следующие форматы: CSV, JSON, Microsoft Excel, HDF5, перо, паркет, рассол и SQL. Это формат, который поддерживается в пандах с to_xxx Методы и обеспечивают локальное хранение данных. Для каждого случая мы посмотрим только на основы API, чтобы мы могли написать и прочитать Dataframe с теми же dataTypes. Для каждого типа мы также посмотрим на несколько основ, таких как размер файла на диске и время, необходимое для чтения и записи данных. Обратите внимание, что это маленький Dataframe. Таким образом, мы не будем изучать истинные преимущества сжатия и скорости для некоторых форматов с меньшим количеством данных. Позже мы можем посмотреть на такие детали.

Примечание. Я не упоминаю об этом формате HTML здесь, поскольку это не очень хороший способ хранения локальных данных, но более полезен для простых веб-записки или создания отчетов. Я также не буду упомянуть Stata или SAS в этой статье, в основном потому, что большинство пользователей не решит использовать либо формат, если они не должны интегрироваться с этими платформами, в этом случае у них не будет много выбора в том, что выберите. Также обратите внимание, что поддержка MsgPack была удалена в PandaS 1.0, поэтому, в то время как в документации это использование, его использование обескуражена вперед.

Для каждого типа хранения я создал метод, который принимает в источнике Dataframe и пишет это в местное хранилище, затем возвращает Dataframe. Это было создано вместе со значениями статистика файла, в котором он хранился. Это позволит нам запустить некоторые тесты по результатам и создать сводную таблицу наших различий.

Я также создал метод сравнения, который будет сравнивать наши оригинальные Dataframe С той, который был написан на диске, а затем воссоздан из сохраненных данных. Это должно быть одинаково, минус небольшие изменения из-за количества значительных цифр, которые используют механизм хранения. В конце этого упражнения я буду использовать эту функцию (которую я написал и отладил при написании этого поста), чтобы убедиться, что я не теряю никаких данных в туристической поездке и воссоздании моих данных.

def compare_dfs(df1, df2):
    # at a minimum, we expect the index to be an exact match
    assert (df1.index == df2.index).all()

    # we also need all the columns to exist
    assert (df1.columns == df2.columns).all()

    for col in df1.columns:
        if df1[col].dtype == 'int64':
            # integer columns will be an exact match
            assert (df1[col] == df2[col]).all()
        elif df1[col].dtype == 'float64':
            # floating point will not be exact, but needs to be close
            assert ((df1[col] - df2[col]).abs() < 1e-10).all()

CSV.

Во-первых, наиболее используемый формат для сохраняющихся данных в мире, вероятно, являются ценностями, или CSV. CSV далеко не идеально в формате, но настолько часто используется, что каждый должен иметь возможность использовать его и понять, что основные проблемы, которые большинство пользователей Pands столкнутся с ним. Dataframe.to_csv. и pd.read_csv Методы имеют ряд аргументов и достойны отдельной статьи. Стоит отметить, что метод pd.read_table просто зовет read_csv Но с вкладкой ( \ t ) в качестве сепаратора вместо запятой. На данный момент мы просто напишем наши цены Dataframe как есть. При чтении нашего CSV нам нужно использовать несколько вариантов для создания аналогичного результата. Во-первых, нам нужно указать нашу индексную колонку, чтобы новый индекс по умолчанию не создан, а во-вторых, мы даем метод подсказкой, что наш индекс столбец представляет собой дату, чтобы ее можно было бы правильно преобразовано.

Преимущества

  • Широко поддерживается
  • Легко манипулировать и отлаживать текстовый редактор или Инструмент электронной таблицы
  • Никакие специальные библиотеки или инструменты не требуются
  • Простые, чтобы сломать набор набора на меньшие куски

Недостатки

  1. Неэффективно
  2. Потеря для некоторых типов данных
  3. Не четкий стандарт, поэтому обычно требует некоторого исследования данных для настройки
  4. Громоздкий для больших наборов данных
def read_and_write_csv(df, filename):
    df.to_csv(filename)
    df2 = pd.read_csv(filename, index_col=0, parse_dates=[0])
    return df2, os.stat(filename)

Json.

Для JSON (JavaScript объектная запись), Dataframe Хранится как один объект с каждым столбцом в качестве элемента этого объекта, состоящий из элементов ключей индекса и значений, являющихся значениями из столбца. Так что это может выглядеть что-то вроде этого:

{"Open":{"511056000000":0.0563667971, ..},
 "Close": {"511056000000":0.0533667232, ..}
}

В общем, я не вижу много людей, использующих JSON в качестве формата хранения для пандов.

Преимущества

  • Широко поддерживается
  • Несколько легко манипулировать и отлаживать текстовый редактор
  • Никакие специальные библиотеки или инструменты не требуются

Недостатки

  • Не самый эффективный и читаемый метод хранения. Редактирование руки не просто.
  • Очень громоздкий с большим набором данных
def read_and_write_json(df, filename):
    df.to_json(filename)
    df2 = pd.read_json(filename)
    return df2, os.stat(filename)

Майкрософт Эксель

Использование пакетов OpenPyXL и XLRD Pandas может читать и записывать файлы Excel. Несмотря на то, что, возможно, не лучший долгосрочный источник хранения, возможность взаимодействия с Excel – очень важная особенность для многих пользователей. Если у рабочие команды имеют данные уже в Excel и поддерживать ее там, возможность прочитать его в Pandas – это необходимая функция. Кроме того, многие третьи лица построят дополнений Excel, поэтому общий рабочий процесс можно сначала тянуть данные в Excel, а затем прочитайте его в Pandas.

Чтобы использовать Excel, вам нужно установить OpenPyXL и XLRD.

Преимущества

  • Excel может сделать отличный редактор данных, и он, скорее всего, будет использоваться предприятиями, чтобы сохранить много ценных бизнес-данных.
  • Многие продавцы интегрируются с Excel, так что это может быть самым быстрым и наиболее надежным способом получения данных в Python

Недостатки

  • Чтобы вручную редактировать файл, вам нужно использовать инструмент электронной таблицы, как Excel
  • Как только несколько рабочих листов хранятся в рабочей книге, жизнь становится немного сложнее
  • Поддержание всех форматирования и формул, не говоря уже о макросах, может быть сложно.
  • Не хорошо для очень больших наборов данных
def read_and_write_excel(df, filename):
    df.to_excel(filename)
    df2 = pd.read_excel(filename, index_col=0)
    return df2, os.stat(filename)

HDF5.

HDF5 – это технологический пакет, который включает в себя модель данных, портативный формат файла, программное обеспечение и набор инструментов для управления сложными объектами данных и метаданными. Для этого примера мы просто посмотрим на базовую постоянство. Однако HDF5 имеет поддержку ряда отличных функций, таких как чрезвычайно большие наборы данных, иерархические данные и сжатие.

Чтобы использовать HDF5, вам нужно установить таблицы.

Преимущества

  • Поддержка больших наборов данных
  • Поддерживает иерархические данные
  • Усовершенствованные инструменты для поддержания данных

Недостатки

  • Более сложность
  • Больше зависимостей
def read_and_write_hdf(df, filename):
    df.to_hdf(filename, key='prices', mode='w')
    df2 = pd.read_hdf(filename, key='prices')
    return df2, os.stat(filename)

Пух Перо

Перо – это формат, разработанный специально для данных DataFrames и написан Pandas Creator, WES Mckinney. Это взаимодействует с R и поддерживает типичные типы данных, которые будут использоваться в Pands DataFrames Такие как временные метки, логические значения, широкий массив числовых типов и категорических значений. Предполагается быть быстрее и эффективнее других форматов. Перо сейчас является частью проекта Apache Arrow.

Чтобы использовать перо, вам нужно установить Pyarrow.

Преимущества

  • Обрабатывает типичные типы данных в DataFrames лучше, чем другие форматы
  • Более эффективным

Недостатки

  • Требует других зависимостей
  • Не так широко поддерживается другими инструментами
def read_and_write_feather(df, filename):
    # Note that feather doesn't allow for non-default indexes, so the index needs to be stored as a column
    df.reset_index().to_feather(filename)
    df2 = pd.read_feather(filename).set_index('Date')
    return df2, os.stat(filename)

Паркет

Паркет – это сжатый, эффективный столбчатый представитель данных, который был разработан для использования в экосистеме Hadoop. Намерение состоит в том, что он поддерживает очень эффективные схемы сжатия и кодирования.

Чтобы использовать паркет, вам нужно установить Pyarrow или Fastparquet.

Преимущества

  • Эффективный
  • Может использовать гораздо меньше места
  • Поддерживает сложные структуры вложенных данных

Недостатки

  • Требует других зависимостей
  • Более сложный
def read_and_write_parquet(df, filename):
    df.to_parquet(filename)
    df2 = pd.read_parquet(filename)
    return df2, os.stat(filename)

Соленый огурец

Марка поддержки также встроена в панды. Для многих пользователей Syble – хороший выбор для быстрого способа сохранения данных и перезагрузить его в другом месте, поскольку он встроен в Python для начала.

Преимущества

  • Широко известный

Недостатки

  • Не по своей сути безопасности не следует доверять при загрузке от внешних источников, поскольку он может привести к выполнению кода
  • Не гарантированно не сможет проснуться объекты из очень старых версий панд
  • Не идеально подходит для обмена данными с пользователями без Python
def read_and_write_pickle(df, filename):
    df.to_pickle(filename)
    df2 = pd.read_pickle(filename)
    return df2, os.stat(filename)

SQL.

Pandas также имеет широкую поддержку баз данных SQL, как для чтения и записи данных. База данных Backeng может быть любая база данных, поддерживаемая SQLALCHEMY с водителем. Но без SQLALCHEMY установлена, отставание – использовать SQLite.

Преимущества

  • Широко используемый
  • Инструменты баз данных являются обильными и могут быть использованы для поддержания данных
  • Высоко вероятно, что многие используют случаи, потребуют запроса базы данных

Недостатки

  • Настройки базы данных могут быть сложными и требуют дополнительной инфраструктуры
  • Драйверы или дополнительные установки необходимы для баз данных, кроме SQLite
import sqlite3

def read_and_write_sql(df, filename):
    conn = sqlite3.connect(filename)
    # so we can rerun this method
    conn.execute('drop table if exists prices')
    # this avoids warnings about spaces in column names
    df.columns = [c.replace(' ', '_') for c in df.columns]
    df.to_sql('prices', conn)
    df.columns = [c.replace('_', ' ') for c in df.columns]

    df2 = pd.read_sql('select * from prices', conn, parse_dates=['Date']).set_index('Date')
    df2.columns = [c.replace('_', ' ') for c in df2.columns]

    return df2, os.stat(filename)

Для быстрого резюме этих методов (которые я писал и отладил сначала), я заберу их все и сравниваю сроки и размеры файлов для каждого. Обратите внимание, что я целенаправленно не выбрал никакого дополнительного сжатия этих данных, даже если он доступен в некоторых форматах. Я также использую довольно небольшой набор набора данных, поэтому улучшения производительности для некоторых форматов не будут отображаться до самого действия с очень большими наборами наборах. Этот выход ниже направляется с сеанса iPython, используя % Timeit магия.

[ins] In [2]: %timeit read_and_write_csv(prices, 'prices.csv')
665 ms ± 91.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[ins] In [3]: %timeit read_and_write_json(prices, 'prices.json')
186 ms ± 30.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[ins] In [4]: %timeit read_and_write_excel(prices, 'prices.xlsx')
7.61 s ± 385 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[ins] In [5]: %timeit read_and_write_hdf(prices, 'prices.h5')
52.9 ms ± 5.76 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

[ins] In [6]: %timeit read_and_write_feather(prices, 'prices.feather')
17 ms ± 1.29 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

[ins] In [7]: %timeit read_and_write_parquet(prices, 'prices.parquet')
52.9 ms ± 4.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

[ins] In [8]: %timeit read_and_write_pickle(prices, 'prices.pkl')
4.79 ms ± 589 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

[ins] In [9]: %timeit read_and_write_sql(prices, 'prices.db')
201 ms ± 19.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

[ins] In [10]: for func, file in [(read_and_write_csv, 'prices.csv'), (read_and_write_json, 'prices.json'),
          ...: (read_and_write_excel, 'prices.xlsx'), (read_and_write_hdf, 'prices.h5'),
          ...: (read_and_write_feather, 'prices.feather'), (read_and_write_parquet, 'prices.parquet'),
          ...: (read_and_write_pickle, 'prices.pkl'), (read_and_write_sql, 'prices.db')]:
          ...: df2, s = func(prices, file)
          ...: compare_dfs(prices, df2)
          ...: print(func, s.st_size/1024)
          ...:
 879.0390625
 1543.609375
 570.5087890625
 556.3828125
 363.087890625
 437.927734375
 548.5615234375
 868.0

С точки зрения времени, довольно ясно, что Sicle является самым быстрым, а HDF5, перо и паркет также довольно быстрые. CSV, JSON и Excel намного медленнее. Я оказался широким распространением времен для ориентира Excel, но это всегда было самым медленным. Базы данных SQL будут сильно зависеть от того, является ли хранение локально или нет, и если удаленный сервер, как быстро сеть и сам сервер базы данных. Это просто быстрый тест, более реалистичный тест будет смотреть на различные уровни сжатия, гораздо больших наборов данных и различных комбинаций требований.

Из-за повторных текстовых данных в файле JSON, это гораздо больше, чем любая из других файлов данных. Мы видим, что перо – самый маленький, с паркетом также меньше, чем большинство других. Для лучшего сравнения мы должны смотреть на варианты хранения каждого метода, поскольку сжатие будет иметь большую разницу в размере, особенно для повторных данных.

Вывод

Таким образом, Pandas имеет широкий спектр вариантов ввода/вывода. Большую часть времени, выбирая, какой вариант для использования будет продиктован форматом, в котором данные уже доступны. При запуске нового проекта, глядя на все варианты – хорошая идея. Этот пост дает быстрый обзор того, что доступен в Пандах, основы вызова этих API и грубое сравнение размера хранения данных и скорости доступа. Надеюсь, это мотивирует вас, чтобы исследовать некоторые другие варианты, которые вы еще не использовали с Pandas.

Оригинал: “https://dev.to/wrighter/overview-of-i-o-tools-in-pandas-3319”