🐼

sqlからpandasを逆引き(SELECT編)

2021/01/03に公開

こんにちは。ヤギユキ(@yagiyuki06)です。

SQLのクエリから、Pandas のメソッドを逆引きする情報を作成しました。
SQLは知っているけど、Pandasはあまり知らないエンジニアのための情報です。

今回は、SQLのSELECT文をターゲットとします。

列選択

SELECT COL1, COL2
FROM TABLE;
df.loc[:, ["COL1", "COL2"]]

条件指定(WHERE)

条件指定は、queryメソッドを使います。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html

一致

SELECT *
FROM TABLE
WHERE COL = 'hoge';
df.query('COL == "hoge"')
# クオテーションに注意

不一致

SELECT *
FROM TABLE
WHERE COL <> 'hoge';
df.query('COL != "hoge"')

大小比較

SELECT *
FROM TABLE
WHERE COL > 1000;
df.query('COL > 1000')

複合条件(または)

SELECT *
FROM TABLE
WHERE COL1 == 'hoge' OR COL2 <> 'huga';
df.query('COL1 == "hoge" or COL2 != "huga"')

複合条件(かつ)

SELECT *
FROM TABLE
WHERE COL1 == 'hoge' AND COL2 <> 'huga';
df.query('COL1 == "hoge" AND COL2 != "huga"')

含む

SELECT *
FROM TABLE
WHERE COL IN (1, 2, 3)';
df.query('COL in (1, 2, 3)')

含まれない

SELECT *
FROM TABLE
WHERE COL NOT IN  (1, 2, 3)';
df.query('COL not in (1, 2, 3)')

範囲

SELECT *
FROM TABLE
WHERE COL BETWEEN 1000 AND 2000;
df.query('COL >= 1000 and date <= 2000')
# pandasのqueryには、betweenという記法はない。

パターンマッチング(前方)

SELECT *
FROM TABLE
WHERE NAME LIKE '中%';
-- NAMEカラムが中で始まる名前の行を抽出 例: 中田
df.query('NAME.str.startswith("田")', engine='python')

パターンマッチング(後方)

SELECT *
FROM TABLE
WHERE NAME LIKE '%中';
-- NAMEカラムが中で終わる名前の行を抽出 例: 田中
df.query('NAME.str.endswith("田")', engine='python')

パターンマッチング(部分)

SELECT *
FROM TABLE
WHERE NAME LIKE '%中%';
-- NAMEカラムが中を含む名前の行を抽出 例: 中田、田中、三田村
df.query('NAME.str.contains("田")', engine='python')

ソート(ORDER BY)

昇順

SELECT *
FROM TABLE
ORDER BY COL ASC;
df.sort_values(by=['COL'], ascending=True)

降順

SELECT *
FROM TABLE
ORDER BY COL DESC;
df.sort_values(by=['COL'], ascending=False)

重複削除(DISTINCT)

SELECT DISTINCT COL1, COL2
FROM TABLE
-- COL1の重複を削除して、COL1とCOL2を選択
df[~df.duplicated(subset=['COL1'])].loc[:, ["COL1", "COL2"]]

集合関数(SUM,MAX,MIN,AVG,COUNT)

SELECT SUM(COL),MAX(COL),MIN(COL),AVG(COL),COUNT(COL)
FROM TABLE
df['COL'].sum() # sum by sql
df['COL'].min() # min by sql
df['COL'].max() # max by sql
df['COL'].mean() # avg by sql
len(df) # count by sql

グループ化(GROUP BY)

グループ化は、groupbyメソッドを使います。
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

SELECT COL1, AVG(COL2)
FROM TABLE
GROUP BY COL1;
df_mean=df.groupby("COL1").mean()
df_mean.loc[:, ["COL2"]]

グループ化の検索(HAVING)

SELECT COL1, AVG(COL2)
FROM TABLE
GROUP BY COL1
HAVING AVG(COL2) > 1000
df_mean=df.groupby("COL1").mean()
df_mean.query("COL2 > 1000").loc[:, ["COL2"]]

Discussion