2012-03-18 118 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