Producir una tabla de resumen (“pivote”?)

Me gustaría una forma de resumir una tabla de base de datos para que las filas que comparten un ID común se resumen en una fila de salida.

Mis herramientas son SQLite y Python 2.x.

Por ejemplo, dada la siguiente tabla de precios de frutas en mis supermercados locales …

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

… Quiero producir una tabla de resumen que muestre el precio de cada fruta en cada supermercado. Los espacios en blanco se deben rellenar con 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 | +----------+----------+----------+----------+ 

Creo que la literatura llama a esto una “tabla dinámica” o una “consulta dinámica”, pero aparentemente SQLite no admite PIVOT . (La solución en esa pregunta utiliza los LEFT JOIN codificados de forma LEFT JOIN . Esto realmente no me atrae porque no conozco los nombres de “columna” de antemano).

En este momento, hago esto mediante la iteración a través de toda la tabla en Python y acumulando un dict de dicts , que es un poco torpe. Estoy abierto a mejores soluciones, ya sea en Python o SQLite, que proporcionarán los datos en forma tabular.

En el lado de Python, puedes usar algo de magia de itertools para reorganizar tus datos:

 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) 

Salida:

 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 

El paquete de pandas puede manejar esto muy bien.

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

La documentación: http://pandas.pydata.org/pandas-docs/stable/reshaping.html

Algunos cuadernos de IPython para aprender pandas: https://bitbucket.org/hrojas/learn-pandas

Espero que eso ayude.
Saludos
Patrick Brockmann