2012-07-11 10 views
5

データベーステーブルをまとめて共通IDを共有する行を1行の出力にまとめる方法をお伝えしたいと思います。サマリー( "ピボット"?)テーブルを作成

私のツールはSQLiteとPython 2.xです。例えば

、私の地元のスーパーマーケットで果物の価格の次の表を与えられた...

+--------------------+--------------------+--------------------+ 
|Fruit    |Shop    |Price    | 
+--------------------+--------------------+--------------------+ 
|Apple    |Coles    |$1.50    | 
|Apple    |Woolworths   |$1.60    | 
|Apple    |IGA     |$1.70    | 
|Banana    |Coles    |$0.50    | 
|Banana    |Woolworths   |$0.60    | 
|Banana    |IGA     |$0.70    | 
|Cherry    |Coles    |$5.00    | 
|Date    |Coles    |$2.00    | 
|Date    |Woolworths   |$2.10    | 
|Elderberry   |IGA     |$10.00    | 
+--------------------+--------------------+--------------------+ 

...私は私に、各スーパーでそれぞれの果物の価格を示すサマリー表を作成します。空白はNULLで埋める必要があります。

+----------+----------+----------+----------+ 
|Fruit  |Coles  |Woolworths|IGA  | 
+----------+----------+----------+----------+ 
|Apple  |$1.50  |$1.60  |$1.70  | 
|Banana |$0.50  |$0.60  |$0.70  | 
|Cherry |NULL  |$5.00  |NULL  | 
|Date  |$2.00  |$2.10  |NULL  | 
|Elderberry|NULL  |NULL  |$10.00 | 
+----------+----------+----------+----------+ 

私は文学は、この「ピボットテーブル」または「ピボットクエリ」と呼ぶと信じて、どうやらSQLite doesn't support PIVOT.(その問題の解決策は、ハードコードさLEFT JOIN Sを使用しています。これは本当に私には興味がないので、私ドン

今私はPythonでテーブル全体を反復し、dictsdictを蓄積することでこれを行いますが、それはビットklutzyです。私は、PythonまたはSQLiteのいずれかの優れたソリューションを公開しており、データを表形式で提供します。 python側で

答えて

8

、あなたのデータを再配置するためのいくつかのitertoolsの魔法を使用することができます。

data = [('Apple',  'Coles',  1.50), 
     ('Apple',  'Woolworths', 1.60), 
     ('Apple',  'IGA',  1.70), 
     ('Banana',  'Coles',  0.50), 
     ('Banana',  'Woolworths', 0.60), 
     ('Banana',  'IGA',  0.70), 
     ('Cherry',  'Coles',  5.00), 
     ('Date',  'Coles',  2.00), 
     ('Date',  'Woolworths', 2.10), 
     ('Elderberry', 'IGA',  10.00)] 

from itertools import groupby, islice 
from operator import itemgetter 
from collections import defaultdict 

stores = sorted(set(row[1] for row in data)) 
# probably splitting this up in multiple lines would be more readable 
pivot = ((fruit, defaultdict(lambda: None, (islice(d, 1, None) for d in data))) for fruit, data in groupby(sorted(data), itemgetter(0))) 

print 'Fruit'.ljust(12), '\t'.join(stores) 
for fruit, prices in pivot: 
    print fruit.ljust(12), '\t'.join(str(prices[s]) for s in stores) 

出力:

Fruit  Coles  IGA  Woolw 
Apple  1.5  1.7  1.6 
Banana  0.5  0.7  0.6 
Cherry  5.0  None None 
Date   2.0  None 2.1 
Elderberry None  10.0 None 
+0

「itertools」の魔法は私の好きな種類の魔法です。他の誰かがSQLiteのソリューションを投稿することを願っていますが、これはすでに私が行っていたことよりも優れています。 –

+0

@ Li-aungYip SQLiteのピボットテーブルのための[サポートしていません](http://www.sqlite.org/cvstrac/tktview?tn=1424)ですので、ここからstackoverflowで〜1000の質問をしてください。しかし、それを行う[perlモジュール](https://github.com/bduggan/SQLite-VirtualTable-Pivot)があります。[here](http://search.cpan.org/~bduggan/SQLite-Pivot) VirtualTable-Pivot-0.02/lib/SQLite/VirtualTable/Pivot.pm)。 – sloth

+0

私は上記のようにピボットテーブルを作成する関数を書くためにこれを使い終えました)、それを一時テーブルとしてデータベースに返します。これにより、ピボットされたデータに対してさらにクエリ( 'JOIN'など)を行うことができます。 テンポラリテーブルはすべて醜いですが、「愚かで動作しても、愚かではありません」 –

12

パンダのパッケージは非常にうまくこれを扱うことができます。

>>> import pandas 
>>> df=pandas.DataFrame(data, columns=['Fruit', 'Shop', 'Price']) 
>>> df.pivot(index='Fruit', columns='Shop', values='Price') 
Shop  Coles IGA Woolworths 
Fruit        
Apple   1.5 1.7   1.6 
Banana  0.5 0.7   0.6 
Cherry  5.0 NaN   NaN 
Date   2.0 NaN   2.1 
Elderberry NaN 10.0   NaN 

ドキュメント: http://pandas.pydata.org/pandas-docs/stable/reshaping.html

一部IPythonノートブックパンダを学ぶために: https://bitbucket.org/hrojas/learn-pandas

役立つことを願っています。
よろしくお願いします。
Patrick Brockmann

関連する問題