60
sqldf for pandas PyCon JP 2015 Ryoji Ishii @airtoxin

sqldf for pandas

Embed Size (px)

Citation preview

sqldf for pandas

PyCon JP 2015 Ryoji Ishii @airtoxin

自己紹介• 石井遼司

• 株式会社ALBERT

• twitter/github/soundcloud→airtoxin

• Python/JavaScript/Scala?

みなさん

pandas使っていますか?

DataFrame便利ですよね

プロットとか

グルーピングdata.groupby(func, axis=0).mean()df.groupby('g').boxplot()

グルーピング

自分で用意した集約関数では…?

data.groupby(func, axis=0).mean()df.groupby('g').boxplot()

apply?

level?

<pandas.core.groupby.DataFrameGroupBy object at 0x10e4684d0>

DataFrameの結合http://pandas.pydata.org/pandas-docs/stable/merging.html

ordered_merge?

append?

merge?

concat?

conbine?

update?

もうSQLでよくね…?

みんなだいすきSQL

airtoxin / pysqldfforked from yhat/pandasql

pysqldfyhat/pandasqlが既にDataFrameにSQL発行できるライブラリを公開していたが、メンテされていなかった。

pandasqlをベースに、クエリ発行が出来るデータ形式を増やしたり、UDFを使えるようにしたり。

SQLite3の構文をサポート。

$ pip install pysqldf

Install

How to use

from pysqldf import SQLDF, load_iris

sqldf = SQLDF(globals()) iris = load_iris()

sqldf.execute("select * from iris;")

union

unionbuyer1

buyer2

unionbuyer1

buyer2

union

buyer = sqldf.execute(""" select name, sex, age from buyer1 union all select name, sex, age from buyer2; """)

unionbuyer1

buyer2

buyer

join

purchase_log

join

buyer

purchase_log

join

buyer

join

purchaser_log = sqldf.execute(""" select * from buyer as b inner join purchase_log as p on b.name = p.buyer; """)

joinpurchaser_log

User Defined Function

UDF表中の値1つを受け取り、値1つを返す関数を定義する。

SQLDFのコンストラクタに辞書形式で関数を渡す。→定義した関数が辞書のkeyで使えるようになる。

UDFdef is_royal_customer(name): if name == "alice": return True else: return False

sqldf = SQLDF(globals(), udfs={ "is_royal_customer": is_royal_customer })

sqldf.execute(""" select *, is_royal_customer(name) as royal from ( select name, sex, age from buyer1 union all select name, sex, age from buyer2 ) """)

UDF

UDF

UDF(aggregate)集約クラスか関数を作成。

集約クラスはsqlite3のドキュメントを参照。

関数はカラムの値のリストを受け取り、値1つを返すようにする。

UDFと同じようにSQLDFのコンストラクタに関数またはクラスを渡すと使えるようになる。

UDF(aggregate)def is_royal_bought(royals): if 1 in royals: return True else: return False

sqldf = SQLDF(globals(), udafs={ "is_royal_bought": is_royal_bought })

UDF(aggregate)

sqldf.execute(""" select item, sum(quantity), is_royal_bought(royal) from purchaser_log group by item """)

UDF(aggregate)

まとめ

purchaser_log = sqldf.execute(""" select * from ( select *, is_royal_customer(name) as royal from ( select name, sex, age from buyer1 union all select name, sex, age from buyer2 ) ) as b inner join purchase_log as p on b.name = p.buyer; """)

purchaser_log

sqldf.execute(""" select name, item, sum(quantity) as cnt from purchaser_log group by name, item """)

sqldf.execute(""" select name, item, sum(quantity) as cnt from purchaser_log group by name, item """).pivot("name", "item", "cnt")

sqldf.execute(""" select name, item, sum(quantity) as cnt from purchaser_log group by name, item """).pivot("name", "item", "cnt").fillna(0)

import seaborn as sns sns.heatmap(pivot, annot=True, linewidths=0.5)

DataFrame meets SQL

💕

みんなつかってくれ!

おわり