2012-03-18 120 views
51

我已经使用熊猫操纵了一些数据,现在我想执行批量保存回数据库。这需要我将数据帧转换为元组数组,每个元组对应于数据帧的“行”。熊猫将数据框转换为元组阵列

我的数据框看起来像:

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. ] 

我如何能有效地做到这一点任何建议?

+1

对于那些在2017+中获得此答案的人,下面有一个[新的惯用解决方案](https://stackoverflow.com/a/34551914/3707607)。你可以使用'list(df.itertuples(index = False,name = None))' – 2017-11-06 16:45:47

回答

96

如何:

subset = data_set[['data_date', 'data_1', 'data_2']] 
tuples = [tuple(x) for x in subset.values] 
+1

非常感谢Wes,比我想出的解决方案更清洁。总的来说,大熊猫的工作很好,我刚刚开始抓表面,但看起来很棒。 – enrishi 2012-03-20 07:08:41

+0

请参阅下面的@ ksindi的答案,使用'.itertuples',这比将数值作为数组并将它们转换为元组更有效。 – vy32 2017-12-21 22:20:11

31

的一般方法:

[tuple(x) for x in data_set.to_records(index=False)] 
31
list(data_set.itertuples(index=False)) 

由于17.1,上面会返回namedtuples名单 - 看到docs

+4

这应该是被接受的答案恕我直言(现在,一个专用功能存在)。顺便说一句,如果你想在你的'zip'迭代器(而不是'namedtuple's)中调用普通'tuple',那么调用:'data_set.itertuples(index = False,name = None)' – Axel 2017-10-25 09:47:07

7

这里的一个矢量化的方法(假设数据帧,data_set被定义为df代替),该返回的tuples一个list如图所示:

>>> 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)] 

设定的想法日期时间列作为索引轴将有助于将Timestamp值转换为其对应的datetime.datetime格式,即通过使用th e convert_datetime64参数DF.to_records,它对DateTimeIndex数据帧这样做。

这将返回一个recarray这可以再制成使用取决于使用情况.tolist


更广义的解决办法是将返回list

df.to_records().tolist()        # Supply index=False to exclude index 
2

更多Python的方式:

df = data_set[['data_date', 'data_1', 'data_2']] 
map(tuple,df.values) 
10

动机
许多数据集足够大,我们需要关注速度/效率。所以我以这种精神提供这个解决方案。它恰好也是简洁的。

为了比较的缘故,让我们放下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)] 

这恰好也是如果我们想要处理一列特定的子集,就很灵活。我们假设我们已经显示的列是我们想要的子集。

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 
+0

你没有公平地表达比较。你的解决方案不比'list(df.itertuples(index = False,name = None))'快。这个答案只会混淆人们。如果我是你,我会删除它。 – 2017-11-06 16:43:48

+0

@TedPetrou为什么不公平?没有人提出你的建议。你为什么不把它作为答案。这两个答案有助于阐明整个问题。 – piRSquared 2017-11-06 17:01:18

+0

这是在这里:https://stackoverflow.com/a/34551914/3707607 – 2017-11-06 17:03:51

0
#try this one: 

tuples = list(zip(data_set["data_date"], data_set["data_1"],data_set["data_2"])) 
print (tuples) 
+0

这不提供问题的答案。要批评或要求作者澄清,请在其帖子下方留言。 - [来自评论](/ review/low-quality-posts/17575022) – 2017-10-09 23:53:41