ラベル Pandas の投稿を表示しています。 すべての投稿を表示
ラベル Pandas の投稿を表示しています。 すべての投稿を表示
2016年9月4日日曜日

Pandas で BigQuery を使うときのメモ

PandasからGoogle BigQueryを使うのは、かなり便利です。 そのときのメモをまとめました。

日付処理

  • BigQueryはUTCです。
  • Pandasのto_datetimeにTimeZone情報を入れる必要がある。
  • 現在の時刻を取る場合

    pd.to_datetime('now').tz_localize('UTC').tz_convert('Asia/Tokyo').to_datetime64()
  • 日本時間を読み取って入れる場合

    pd.to_datetime(datestr, format='%Y年%m月%d日 %H時%M分').tz_localize('Asia/Tokyo').to_datetime64()
  • 扱う方針を決める。
  • UTCに変換する
  • JSTの値をそのまま入れて、タイムゾーンを完全にユーザが管理する

Insert(to_gbq)

  • カラム定義、カラム順など揃える必要がある。
  • 既存のテーブルにto_gbqで、入れるのは調整が手間。
  • 可能なら、最初からto_gbqでテーブルを作った方が良い。
  • 定期的に追加するなら、if_existsを使う。
df.colomns
['gcol2','no_append','gcol1']
# 必要なカラムだけ指定
gdf = df[['gcol1', 'gcol2']]
gdf.to_gbq(table, projectid, private_key, if_exists='append')

pandas からgenerate_bq_schema は使わない

  • スキーマ作成だけ行うgenerate_bq_schemaですが、Duplicateになっています。
  • Creating BigQuery Tables
  • 代わりに上記to_gbqで行います。
  • もしくはbq loadで行います。
  • bq quickstart

import gcpとは

検索すると出てくる

import gcp.bigquery ad bq

これはDataLabの組み込みライブラリです。DataLabから使用します。

2016年8月28日日曜日

GCPのBigQueryを使ってみました

BigQueryを使ってみたので、関連情報をまとめました

GCP NoSQL を使ってデータ処理したい時

主なサービスはこの辺りだと思います。

今回は、格安で比較的枯れているBigQueryを使ってみました。 以降の記事はBigQueryについてです。

オライリー本もあります。 Google BigQuery

課金について

ビッグデータをCloudサービスで使う時、課金方式をよく把握しておくのは必須です。

  • データ保存による: 1TB 1ヶ月 $20
  • スキャンデータ量による
  • BigQueryで150万円溶かした人の顔
  • 300GBに対して、フルスキャンを数百回繰り返した。(テーブル切り分けのために、select insert)
  • 価格体系が今後変わる。computing量による感じに。
  • ストリーミングは課金: 10万行単位などバルクインサートより高い。
  • 費用的には、Cloud Storageなどにデータを置いて、バルクインサートが良い。
  • ストリーミングの方が手間は少ない(Fluentdや、以下のPandasなどで直接インサートできる)
  • ストリーミングはデータ落ちなどが発生する模様。

BigQuery の課金仕様と注意点をまとめてみた(2015-07 時点)

課金対策ツール

使い方

Pythonから使う場合がメインです。

データ分析基盤としての BigQuery 運用のベストプラクティス Python使いのためのBigQuery連携

また、SDKが提供されてない言語でも、REST APIから使えます。 BigQuery クライアント ライブラリ

その場合、OAUTH2認証が必要です。

CLIで使う

Googleが提供している、基本のbqコマンドです。

bq コマンドライン ツール クイックスタート

インタラクティブに使う

GCPのコンソールからのやり方です。

Quickstart Using the Web UI

Jupyter(IPython)ベースのインタラクティブツールもあります。
Betaですが、Jupyterはかなり使いやすいので、こちらもオススメです。

Google Cloud Datalab 上のページのCLOUD DATALAB を起動は使えなくなってる模様。立ち上げはこちらから。dockerを使って起動する。 quickstart

アプリで使う(ライブラリ)

  • Pandas: io.gbqパッケージがあり、read_gbqto_gbqが用意されてます。pandas使っている方ならこれ一択かと。かなり使いやすいです。
  • Pythonのclientライブラリ: BigQuery-Pythonがあります。Pandas使ってない方はこちらが候補になると思います。使いやすいです。
  • 公式API:上記でできないことがある場合以外、直接触ることはないです。ライブラリ作成者向けだと思います。
Pandas

to_gbqinsertすると、ストリーミングになり、課金対象になります。
大量データを入れる場合は計算した方が良いです。

pandas連携が詳しく載ってるので再掲します。

Python使いのためのBigQuery連携 pandas.io.gbq.read_gbq pandas.io.gbq.to_gbq

Python client

BigQuery-Python PythonからBigQueryを操作するときは BigQuery-Python が便利だった

公式API

BigQuery API クイックスタート BigQuery API Client Library for Python getting_started.py Google Application Default Credentials

2016年8月27日土曜日

pandasでの簡単な日付処理

pandasは、日付処理も充実しています。

すぐに使える関数をまとめました。

準備

import pandas as pd

日付に変換

Stringから作成する場合。

> pd.to_datetime('2016-08-26 00:00:00')
Timestamp('2016-08-26 00:00:00')

to_datetimeは、かなり賢く以下のような入力がデフォルトで正しくパースされます。

> pd.to_datetime('2016/8/26 0:0')
> pd.to_datetime('2016/8/26')
> pd.to_datetime('20160826')
> pd.to_datetime('160826 0000')
Timestamp('2016-08-26 00:00:00')

ただし、日付6桁は欧米式にパースされます。

> pd.to_datetime('260816 0100')
Timestamp('2016-08-26 01:00:00')

Python pandas で日時関連のデータ操作をカンタンに

日ごと、月ごと、年ごとに処理

年月日を取り出します。

> pd.to_datetime('2016-08-26 0:0:0').year
2016

> pd.to_datetime('2016-08-26 0:0:0').month
8

> pd.to_datetime('2016-08-26 0:0:0').day
26

dtを使うとdatetime64型の要素のプロパティに直接アクセスできます。

> df['date1']
0   2016-08-26
1   2016-08-27
Name: date1, dtype: datetime64[ns]

> df['date1'].dt.month
8

groupbyする場合です。

# 各カラムを月別に合計
df.groupby(df['date1'].dt.month).sum()

# グルーピングしたデータを取得
df.groupby(df['date1'].dt.month).groups

Python pandas アクセサ / Grouperで少し高度なグルーピング/集計

2016年8月26日金曜日

pandasでmysqlに接続する in debian

ライブラリインストールから、接続までまとめました。

mysql-connector-python + pandas.io.sqlです。

setup

リポジトリからが簡単に入ります。

$  git clone https://github.com/mysql/mysql-connector-python.git
$  cd mysql-connector-python
$  python ./setup.py build
$  sudo python ./setup.py install

condaを使ってる場合です。

$ conda install -c https://conda.anaconda.org/anaconda mysql-connector-python 

ディストリビューションからも取れる模様。

$ sudo apt-get install python3-mysql.connector

参考

python+pandasで大規模データを扱うときのメモ
Python3でMySQLに接続する環境をLinuxで整える
macでのmysql-connector-pythonインストール方法

DataFrameをテーブルから直接作る

import mysql.connector as mc
import pandas.io.sql as pdsql

con = mc.connect(
  user ='USER',
  password='PW',
  host='localhost',
  database='DB')

sql = 'SELECT * FROM table'

df = pdsql.read_sql(sql, con)
# ここでそのまま使えます。

con.close

参考

pandasでRDBの読み書きをする

2016年8月21日日曜日

Pandasの基本的でよく使いそうな機能のメモ

Pandasの基本的ですが、実際によく使いそうな使い方のメモです。

インストールについて

こちらが非常に詳しいです。 anacondaを使って環境構築します。

Google Compute Engine + Debian で実行しましたが、問題なく動いてます。

データサイエンティストを目指す人のpython環境構築 2016

csv形式のStringからデータを読み取る。

Stringから直接csvデータを読み込むこともできます。 http://stackoverflow.com/questions/22604566/how-to-create-a-pandas-dataframe-from-string

import sys
from io import StringIO

d = StringIO("""a,b,c
1,2,3
11,12,13
""")

df = pd.read_csv(d)

データフレームを連結する

Python Pandasでのデータ操作の初歩まとめ − 前半:データ作成&操作編 pandasでindexの連番を振り直す

concatもしくは、append関数を使います。

行を追加する場合も、DataFrameの連結で行います。

  • concatは対象とするDataFrameをリストにして渡します。
  • appendはdf.appendという書き方になるので、直接行を追加する場合に便利です。
  • どちらもデフォルトでは、非破壊的な動作になっています。

行方向に追加

concatを使って連結

// axis=0 (デフォルト。省略可能)
concated_df = pd.concat([df1, df2])

ちなみに、カラム名が異なると、カラムは全て残り、互いの欠損箇所には、NA値が挿入されます。

欠損値を埋めたい場合は、fillnaを使います。統計処理で必要とされる、平均値補完、線形補間なども簡単にできます。

// 0埋め
df.fillna(0)
// 平均値
df.fillna(df.mean())
// 線形補間
df.interpolate()
// na値削除(行ベース)
df.dropna()
// na値削除(列ベース)
df.dropna(axis=1)

appendを使って行をその場で追加

// columnsを既存のものから取ってきて同じ構造にします
appended_df = df.appned(pd.DataFrame([[1,2,3]], columns = df.columns.tolist())

列方向に追加

pd.concat([df1, df2], axis=1)

同じくインデックスが違うと列方向にNA値が挿入される。

新しい列をその場で追加する方法は、こちらが簡単です。 ただ、dfを直接書き換えるので注意が必要です。

df['c_new'] = [1,2,3]

インデックス・カラムの貼り直し

行番号の貼り直し

concated_df.reset_index(drop=True)

//直接生成時に貼り直すこともできる
pd.concat([df1,df2]).reset_index(drop=True)

カラム名の貼り直し

// dfインスタンスに対して設定
concated_df.columns = ["c1","c2","c3","c4","c5","c6"]

表記ブレをなくすよう変更

// 全て小文字にして、スネークケースにする。記号も開きました。
df.columns = [s.lower().replace(' ', '_').replace('?', '_bool') for s in df.columns.tolist()]

SQLのような処理を行う

よくまとまっていてオススメです。

pandasにsqlでよくやる処理をやらせてみる

sort

sort_valuesを使う方が推奨のようです。

df.sort_values(by="col1")

ERROR

CSVのパースエラー

CSVを読み込む時に、パースエラーが発生しました。

> df = pd.read_csv("file.csv")

pandas/parser.pyx in pandas.parser.TextReader.read (pandas/parser.c:8748)()

pandas/parser.pyx in pandas.parser.TextReader._read_low_memory (pandas/parser.c:9003)()

pandas/parser.pyx in pandas.parser.TextReader._read_rows (pandas/parser.c:9731)()

pandas/parser.pyx in pandas.parser.TextReader._tokenize_rows (pandas/parser.c:9602)()

pandas/parser.pyx in pandas.parser.raise_parser_error (pandas/parser.c:23325)()

CParserError: Error tokenizing data. C error: EOF inside string starting at line 244276

ここで line 244276 は、ファイル上の行数でないので注意が必要です。

この時は結果的に、csvファイルの最終行のデータがおかしくなっていためエラーになっていました。

それでも解決しない場合は、この辺りが参考になると思います。

ISSUEが立っていますが、この問題は現在は、フィックスされてるよう。 https://github.com/pydata/pandas/issues/5501

カラムが多すぎるとExceptionを吐くが、それらを削除して読み込む。

pd.read_csv("file.csv", error_bad_lines=False)

エンコーディングとエンジンを指定する

pd.read_csv("file.csv", encoding='utf-8', engine='c')
pd.read_csv("file.csv", encoding='utf-8', engine='python')

quotingを指定する

import csv
pd.read_csv("file.csv", quoting=csv.QUOTE_NONE)

文字列として読み込んで解析する

f = open("file.csv")
s = f.read()
l = f.readlines()
2016年8月20日土曜日

Pandasで実践的(というか実務的)なデータを扱う

実務的なデータをさっと処理したい場合、

  • SQL
  • スクリプト言語
  • Shell/AWK
  • Excel

あたりがよく使われると思います。

ここでは、スクリプト言語の一つになると思いますが、Python+Pandas紹介します。

Pandasは、Pythonのデータ処理用ライブラリで、DataFrameというExcelのスプレッドシートのようなオブジェクトを使って処理します。DataFrameはもともとS言語/Rに実装されていたものです。

Pandasの特徴である強力で豊富な統計処理の紹介が多いですが、実務データの処理もかなり使えます。

準備

ipython

pythonの対話実行環境としては、ipythonは必須です。 ファイルのタブ補完も効くのでサクサクできます。

pip install ipython

Pandasのimport

ここからは、事前にこのようにimportしていることを前提とします。

import pandas as pd
import numpy as np

データ読み取り

csvファイルの場合。

df = pd.read_csv("a.csv")

URLや桁区切りのカンマにも強いtsvファイルはこちら。

df = pd.read_csv("a.tsv", sep="\t")

ファイルにはヘッダを入れた方がいいです。

PandasのDataFrameはヘッダ情報もきちんと読み取り、列名称で値を指定することが可能なためです。

マージ(join)

現実の業務処理では、joinはかなり需要があると思います。

Pandasももちろんできますが、どちらかというと、統計処理で必要な行を追加していく(union系)の処理の紹介が多いと思います。

Pandasでのマージの仕方。

// キー名が違う場合
merged = pd.merge(df1, df2, left_on = 'id1', right_on = 'id2')
// キー名が同じ場合
merged = pd.merge(df1, df2, on = 'id') 

mergeメソッドは、オプションも豊富です。

行ごとに処理

必要なデータが一つの表にまとまったら、行ごとに処理をしたいですね。

しかもこのロジックはかなり複雑になることがあります。

SQLで複雑なCASE文を書くよりもスクリプト言語で書いた方がすっきりする場合も多いです。

オススメはiterrowsを使うことです。applymapを使うと、関数を渡してシンプルに記述できるのですが、カラム名が使えなくなります。

df['new'] = ""
for key, record in df.iterrows():
  if record["column1"] in ["a", "b"]:
    ...複雑なロジック
    df.loc[key, 'new'] =  "column1 is " + record["column1"]

また、ここはPandasの強力なスライシング処理によって、必要なデータを取得することが可能なのでロジックを簡潔にすることが可能です。

こちらはapplyを使って行ごとに処理する場合。

def f(s):
  print s

df.apply(f, axis=1)

csv/tsvへの出力

非常にシンプルです

csv

df.to_csv("b.csv")

import csv
df.to_csv("b.csv", quoting=csv.QUOTE_ALL)

tsv

df.to_csv("b.csv", sep="\t")

まとめ

各ステップでは、そこに強い言語やツールがあるかと思います。

Python+Pandasは一通り扱えることがメリットだと思います。

一旦、DataFrameに取り込んでしまえば、手続き的な処理、集計処理ともにかなり柔軟に処理ができます。