Я обработал некоторые данные с помощью панд, и теперь я хочу выполнить пакетное сохранение обратно в базу данных. Это требует, чтобы я преобразовал фрейм данных в массив кортежей, причем каждый кортеж соответствует «строке» фрейма данных.
Мой DataFrame выглядит примерно так:
In [182]: data_set
Out[182]:
index data_date data_1 data_2
0 14303 2012-02-17 24.75 25.03
1 12009 2012-02-16 25.00 25.07
2 11830 2012-02-15 24.99 25.15
3 6274 2012-02-14 24.68 25.05
4 2302 2012-02-13 24.62 24.77
5 14085 2012-02-10 24.38 24.61
Я хочу преобразовать его в массив кортежей, например:
[(datetime.date(2012,2,17),24.75,25.03),
(datetime.date(2012,2,16),25.00,25.07),
...etc. ]
Любые предложения о том, как я могу это сделать эффективно?
list(df.itertuples(index=False, name=None))
df.to_records(index=False)
и список диктовок:df.to_dict('records')
Ответы:
Как насчет:
для панд <0,24 используйте
источник
.itertuples
, который будет более эффективным, чем получение значений в виде массива и их преобразование в кортеж.Начиная с 17.1, приведенное выше будет возвращать список именованных кортежей .
Если вам нужен список обычных кортежей, передайте
name=None
в качестве аргумента:источник
tuple
s в своемzip
итераторе (вместоnamedtuple
s), тогда звоните:data_set.itertuples(index=False, name=None)
itertuples
медленно . Избегайте, если возможно. Для циклов (как показано в принятом ответе) в этих случаях обычно быстрее.Общий способ:
источник
data_set.to_records(index=False).tolist()
лучше?Мотивация
Многие наборы данных достаточно велики, поэтому нам нужно заботиться о скорости / эффективности. Поэтому я предлагаю это решение в том же духе. Это тоже бывает лаконично.
Для сравнения опустим
index
столбецРешение
Предлагаю использовать
zip
иmap
Это также может быть гибким, если мы хотим иметь дело с определенным подмножеством столбцов. Предположим, что уже отображаемые столбцы являются желаемым подмножеством.
Что быстрее?
Выход
records
происходит быстрее всего, за ним следуют асимптотически сходящиесяzipmap
иiter_tuples
Я воспользуюсь библиотекой
simple_benchmarks
из этого постаПроверить результаты
источник
Вот Векторизованный подход (при условии , dataframe,
data_set
чтобы определить , какdf
вместо этого) , что возвращаетlist
из ,tuples
как показано ниже:производит:
Идея установки столбца datetime в качестве оси индекса состоит в том, чтобы помочь в преобразовании
Timestamp
значения в соответствующийdatetime.datetime
эквивалент формата, используяconvert_datetime64
аргумент, вDF.to_records
котором это делается дляDateTimeIndex
фрейма данных.Это возвращает a,
recarray
который затем можно заставить вернутьlist
using.tolist
Более обобщенное решение в зависимости от варианта использования:
источник
Самый эффективный и простой способ:
Вы можете отфильтровать нужные столбцы перед этим вызовом.
источник
Этот ответ не добавляет ответов, которые еще не обсуждались, но вот некоторые результаты скорости. Думаю, это должно решить вопросы, которые возникли в комментариях. Все они выглядят так, как будто они O (n) , на основе этих трех значений.
TL; DR :
tuples = list(df.itertuples(index=False, name=None))
иtuples = list(zip(*[df[c].values.tolist() for c in df]))
самые быстрые.Я провел быстрый тест на скорость трех предложений здесь:
tuples = list(zip(*[df[c].values.tolist() for c in df]))
tuples = [tuple(x) for x in df.values]
name=None
предложением от @Axel:tuples = list(df.itertuples(index=False, name=None))
Маленький размер:
дает:
Изображение большего размера:
дает:
Столько терпения, сколько у меня:
дает:
Версия zip-архива и версия itertuples находятся в пределах доверительных интервалов друг друга. Я подозреваю, что они делают то же самое под капотом.
Хотя эти тесты скорости, вероятно, не имеют отношения к делу. Расширение пределов памяти моего компьютера не занимает много времени, и вам действительно не следует делать это с большим набором данных. Работа с этими кортежами после этого окажется действительно неэффективной. Маловероятно, что это будет серьезным узким местом в вашем коде, поэтому просто придерживайтесь той версии, которую считаете наиболее читаемой.
источник
[*zip(*map(df.get, df))]
некоторое время пользуюсь . Во всяком случае, подумал, тебе будет интересно.источник
Преобразование списка фреймов данных в список кортежей.
источник
Более питонический способ:
источник
map()
заведомо непифоничен.