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






вместо этого используйте функцию 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)
Это один из миллионов элементов в списке. Поэтому для этого мне нужно перебрать список, содержащий вложенные словари, и, следовательно, это будет очень медленно.
@Terjeja Если вы хотите переместить Open, High и т. д. в отдельный столбец, попробуйте использовать сводную функцию pandas.pydata.org/pandas-docs/stable/reference/api/…, если у вас будут ошибки для дублирующихся данных, используйте сводную_таблицу вместо среднего
Спасибо, но я не думаю, что это увеличит скорость, так как мне придется повторять функцию поворота несколько миллионов раз. Или я что-то упускаю?
Что-то вроде этого будет работать (ваш входной список называется 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
Не могли бы вы уточнить желаемый результат?