Размещение словаря в Pandas DataFrame

Я загружаю финансовые данные, которые входят в словари в списках в Python, выглядящие следующим образом:

[{'complete': True,
  'volume': 2,
  'time': '2004-05-31T21:00:00.000000000Z',
  'mid': {'o': '6.07260', 'h': '6.07260', 'l': '6.07260', 'c': '6.07260'}},
 {'complete': True,
  'volume': 2,
  'time': '2004-06-01T21:00:00.000000000Z',
  'mid': {'o': '6.08790', 'h': '6.08790', 'l': '6.08790', 'c': '6.08790'}}]

У меня довольно много миллионов таких точек данных, которые я хотел бы использовать в Pandas.

До сих пор я использовал следующий код:

    v = []
    for keys in [x.split(":") for x in m.keys()]:
        _v = r.get(keys[0])
        for k in keys[1:]:
            _v = _v.get(k)
        v.append(_v)

    return v

record_converter = convrec if conv is None else conv
column_map_ohlcv = OrderedDict([
   ('time', 'Date'),
   ('mid:o', 'Open'),
   ('mid:h', 'High'),
   ('mid:l', 'Low'),
   ('mid:c', 'Close'),
   ('volume', 'Volume')
])
cmap = column_map_ohlcv if colmap is None else colmap
df = pd.DataFrame([list(record_converter(rec, cmap)) for rec in r.get('candles')])
df.columns = list(cmap.values())

Это работает, но не очень быстро, так как мне нужно разделить «середину» на разные столбцы?

Есть ли более прямой способ получить его в фрейме данных без использования цикла? Как, например, использование numpy или pandas для выполнения тяжелой работы?

Желаемый результат должен быть фреймом данных Pandas, который выглядит примерно так:

Date                    Open    High    Low     Close   Volum

2004-05-31 21:00:00    6.0726   6.0726  6.0726  6.0726  2
2004-06-01 21:00:00    6.0879   6.0879  6.0879  6.0879  2

Не могли бы вы уточнить желаемый результат?

Cleb 31.01.2019 22:24

Что это за файл? Бинарный или текстовый файл? Я думаю, что проще предварительно обработать его и просто удалить всю избыточную информацию (например, словари). Нет причин, по которым этот файл не является просто CSV-файлом из фрагмента, который вы разместили.

Jan Christoph Terasa 31.01.2019 22:48
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
834
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

вместо этого используйте функцию pandas, это будет быстрее и проще. Например, это может быть хорошей отправной точкой. Я добавил переименование индексов и поворот, чтобы сделать столбцы Close, High, Low, Open, если это необходимо:

import pandas as pd

d = {'complete': True,
 'volume': 2,
 'time': '2004-05-31T21:00:00.000000000Z',
 'mid': {'o': '6.07260', 'h': '6.07260', 'l': '6.07260', 'c': '6.07260'}}

df = pd.DataFrame(d)
df.rename(index = {'o': 'Open', 'h': 'High', 'l': 'Low', 'c': 'Close'}, inplace=True)
df['column'] = df.index

df = pd.pivot_table(df, columns=['column'], index=['complete', 'time', 'volume'], values=['mid'], aggfunc=np.sum)
pd.set_option('display.max_columns', 1000)

Это один из миллионов элементов в списке. Поэтому для этого мне нужно перебрать список, содержащий вложенные словари, и, следовательно, это будет очень медленно.

Oeyvind 31.01.2019 22:26

@Terjeja Если вы хотите переместить Open, High и т. д. в отдельный столбец, попробуйте использовать сводную функцию pandas.pydata.org/pandas-docs/stable/reference/api/…, если у вас будут ошибки для дублирующихся данных, используйте сводную_таблицу вместо среднего

Hubert Dudek 31.01.2019 22:33

Спасибо, но я не думаю, что это увеличит скорость, так как мне придется повторять функцию поворота несколько миллионов раз. Или я что-то упускаю?

Oeyvind 31.01.2019 22:46
Ответ принят как подходящий

Что-то вроде этого будет работать (ваш входной список называется l):

tempdf = pd.DataFrame(l)

что дает

   complete                                                mid                            time  volume
0      True  {'o': '6.07260', 'h': '6.07260', 'l': '6.07260...  2004-05-31T21:00:00.000000000Z       2
1      True  {'o': '6.08790', 'h': '6.08790', 'l': '6.08790...  2004-06-01T21:00:00.000000000Z       2

Теперь вы можете разделить словарь в mid на несколько столбцов и использовать concat:

df = pd.concat([tempdf.drop('mid', axis=1), tempdf['mid'].apply(pd.Series)], axis=1)

что дает желаемый результат:

   complete                            time  volume        o        h        l        c
0      True  2004-05-31T21:00:00.000000000Z       2  6.07260  6.07260  6.07260  6.07260
1      True  2004-06-01T21:00:00.000000000Z       2  6.08790  6.08790  6.08790  6.08790

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