Панды преобразуют фрейм данных в массив кортежей
Я манипулировал некоторыми данными с помощью панд, и теперь я хочу выполнить пакетное сохранение обратно в базу данных. Это требует от меня преобразования фрейма данных в массив кортежей, причем каждый кортеж соответствует "строке" фрейма данных.
мой фрейм данных выглядит примерно так:
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. ]
любые предложения о том, как я могу эффективно сделать это?
7 ответов:
Как насчет:
subset = data_set[['data_date', 'data_1', 'data_2']] tuples = [tuple(x) for x in subset.values]
list(data_set.itertuples(index=False))
начиная с 17.1, выше будет возвращен список namedtuples-см. docs.
мотивация
Многие наборы данных достаточно велики, что мы должны заботиться о скорости/эффективности. Поэтому я предлагаю это решение в таком духе. Это также бывает кратким.Для сравнения, давайте отбросим
index
колонкиdf = data_set.drop('index', 1)
решение
Я предложу использоватьzip
и пониманияlist(zip(*[df[c].values.tolist() for c in df])) [('2012-02-17', 24.75, 25.03), ('2012-02-16', 25.0, 25.07), ('2012-02-15', 24.99, 25.15), ('2012-02-14', 24.68, 25.05), ('2012-02-13', 24.62, 24.77), ('2012-02-10', 24.38, 24.61)]
он также может быть гибким, если мы хотим иметь дело с a конкретное подмножество столбцов. Мы предположим, что столбцы, которые мы уже показали, являются подмножеством, которое мы хотим.
list(zip(*[df[c].values.tolist() for c in ['data_date', 'data_1', 'data_2'])) [('2012-02-17', 24.75, 25.03), ('2012-02-16', 25.0, 25.07), ('2012-02-15', 24.99, 25.15), ('2012-02-14', 24.68, 25.05), ('2012-02-13', 24.62, 24.77), ('2012-02-10', 24.38, 24.61)]
все следующие дают те же результаты
[tuple(x) for x in df.values]
df.to_records(index=False).tolist()
list(map(tuple,df.values))
list(map(tuple, df.itertuples(index=False)))
что быстрее?
zip
и понимание быстрее на большой маржа%timeit [tuple(x) for x in df.values] %timeit list(map(tuple, df.itertuples(index=False))) %timeit df.to_records(index=False).tolist() %timeit list(map(tuple,df.values)) %timeit list(zip(*[df[c].values.tolist() for c in df]))
мелкие сведения
10000 loops, best of 3: 55.7 µs per loop 1000 loops, best of 3: 596 µs per loop 10000 loops, best of 3: 38.2 µs per loop 10000 loops, best of 3: 54.3 µs per loop 100000 loops, best of 3: 12.9 µs per loop
большие объемы данных
10 loops, best of 3: 58.8 ms per loop 10 loops, best of 3: 43.9 ms per loop 10 loops, best of 3: 29.3 ms per loop 10 loops, best of 3: 53.7 ms per loop 100 loops, best of 3: 6.09 ms per loop
вот векторизованный подход (предполагая фрейм данных,
data_set
определяется какdf
вместо этого), что возвращаетlist
наtuples
как показано ниже:>>> df.set_index(['data_date'])[['data_1', 'data_2']].to_records().tolist()
выдает:
[(datetime.datetime(2012, 2, 17, 0, 0), 24.75, 25.03), (datetime.datetime(2012, 2, 16, 0, 0), 25.0, 25.07), (datetime.datetime(2012, 2, 15, 0, 0), 24.99, 25.15), (datetime.datetime(2012, 2, 14, 0, 0), 24.68, 25.05), (datetime.datetime(2012, 2, 13, 0, 0), 24.62, 24.77), (datetime.datetime(2012, 2, 10, 0, 0), 24.38, 24.61)]
идея установки столбца datetime в качестве оси индекса заключается в том, чтобы помочь в преобразовании
Timestamp
значение ему соответствуетdatetime.datetime
эквивалент формата, используя