データアナリストくんのblog

データアナリストとして働いている人がちょっと調べる内容をまとめるブログ

Pandasで文字型の数値を数値型に強制変換する

import pandas as pd
### dfは任意のpd.DataFrame()
### colは変換させたいカラム
df.col = pd.to_numeric(df.col, errors='coerce')

.astype(int) でも変換できるが、欠損値が含まれている場合エラーが発生し変換が行われない。
to_numeric の errors を使うことで数値に変換できるものは変換し、それ以外のものは NaN に変換する。
errors は、"ignore", "raise", "coerce" の3つの値をとる。

pandas.pydata.org

GAデータをAthenaで操作する

会社のDBにメディアのGA(Goole Analytics)ログがあって操作するときに
色々と今までのデータとは毛色が違ったので忘れないように。
※一般的なGAログがどのような形で格納されているか分からないので、あくまで知っている内容で書きます。


struct型でデータが入力されている

まずは、どんな形で入っているか
Pythonだとdictの様な形で入っている

# TableのDDL(totalsカラム)
struct<visits:int,hits:int,pageviews:int,timeonsite:int,bounces:int,transactions:int,transactionrevenue:int,newvisits:int,screenviews:int,uniquescreenviews:int,timeonscreen:int,totaltransactionrevenue:int,sessionqualitydim:int>

# SELECTでの表示例
{visits=1, hits=5, pageviews=5, timeonsite=76, bounces=null, transactions=null, transactionrevenue=null, newvisits=null, screenviews=null, uniquescreenviews=null, timeonscreen=null, totaltransactionrevenue=null, sessionqualitydim=0}

上記でtotalsの中のhitsやtimeonsiteを取ってきたい場合、

SELECT totals.hits, totals.timeonsite
FROM {table_name}

の感じで、「.」で繋げれば抽出することができる。


array型でデータが入力されている

# TableのDDL(customdimensionsカラム)
array<struct<index:int,value:string>> 

# SELECTでの表示例
[{index=20, value=hpsk16064}, {index=29, value=undefined}, {index=14, value=,}, {index=1, value=Mozilla/5.0 (Linux; Android 8.1.0)}, {index=26, value=fukuoka}]
# 抽出パターン1: arrayの位置で取得(1番目の要素を抽出)
# →Pythonと違って一番最初の要素は1から始まる
SELECT customdimensions[1]

# 抽出パターン2: arrayを要素ごとに行に変換
# →要素分の行数に分解される
SELECT cus_unnest
FROM {table_name}
CROSS JOIN UNNEST (customdimensions) as t(cus_unnest)

抽出パターン2で欲しい要素(例だとindex)が決まっていればWHERE句で条件つけてもよい。

もしもっといい方法あればコメントで教えてください!

AWS Athena(Presto)で時間処理

いつも時間処理系のクエリを忘れてしまうのでメモ。。。
Presto time関連のドキュメント

文字型からdatetime型

'YYYY-MM-DD'
→ DATE(time_col)

'YYYY-MM-DDTHH:mm:ss+zzzz'
→ from_iso8601_timestamp(time_col)

'YYYYMMDD'
→ DATE_PARSE(time_col, '%Y%m%d')

単純に変換
→ TRY_CAST(time_col AS timestamp)

※TRY_CASTはCASTでも可。変換できないものをNULLにしてくれるのでTRYの方をよく使っている。

datetime型から文字型

特定の形に変換
→ DATE_FORMAT(time_col, 'time_format') 
 or
 FORMAT_DATETIME(time_col, 'time_format')
ex) DATE_FORMAT(time_col, '%Y-%m-%d %H:%i:%s')

単純に変換
→ TRY_CAST(time_col AS varchar)

time_format部分のドキュメント

サイズの大きいファイルをLinuxで表示

Linuxで大きいサイズのデータを探すコマンド

find /home -size +100M | xargs ls -l

意味:/homeディレクトリ配下で100MB以上のデータを表示

上記だとデータサイズはキロバイトで表示されるのでMBやGBで表示したい場合は以下

find /home -size +1000M | xargs ls -lh

Pandas DataFrame の表示件数を増やす

import pandas as pd

pd.set_option('display.max_columns', 100) # 表示させるカラム数を増やす
pd.set_option('display.max_rows', 100) # 表示させる行数を増やす

Pythonで日付の計算をする

今回は Python で日付の足し算(引き算)やある日付までの日数を計算します。

from datetime import datetime, timedelta

最初にある日付に i 日足す(引く)場合

date = '2023-02-15'
delta = 3 # 足し引きしたい日数
date2 = datetime.strftime(datetime.strptime(date, '%Y-%m-%d') + timedelta(days=delta), '%Y-%m-%d')
print(date2)

ある日付からある日付までの日数を求める場合

strdt = datetime.strptime('2023-02-01', '%Y-%m-%d') #開始日
enddt = datetime.strptime('2023-02-15', '%Y-%m-%d') #終了日
days_num = (enddt - strdt).days + 1 # strdt から enddt までの日数
print(days_num)

### おまけ
# strdt から enddt までの日付を list に格納する
datelist = []
for i in range(days_num):
    datelist.append(datetime.strftime(strdt + timedelta(days=i), '%Y-%m-%d'))

print(datelist)

AWS Athenaにawswranglerを用いてテーブルを作成

普段の業務でクラウドサービスとしてAWSを利用しています。
データ集計業務や分析ではAthenaというサービスを使ってますが、SQLでは面倒な処理(pivotなど)はPythonでやりたくなります。
PythonからAthena上にテーブルを作る際に便利なpakcage「awswrangler」があるので紹介です!
※AthenaはGlue Datacatalogを参照してますので、テーブル定義などはDatacatalog側にあります。

もしawswranglerがinstallされていない場合はinstallしてください。
(PyPIドキュメント)https://pypi.org/project/awswrangler/

pip install awswrangler
import awswrangler as wr

# df変数にテーブル元になるdataframeを格納しておく。
wr.s3.to_parquet(
    df=df,
    path='s3://bucket/prefix/',
    table='sample_table',
    database='sample_database',
    mode='overwrite', # appendにすればデータを追加。overwriteは上書きなので元あるデータは消えます。
    dataset=True,
    partition_col=['{partition_name}'], # partitionがない場合は削除、複数ある場合はリスト内に追加すればokです。
    max_rows_by_file=int(1e6) # これがない場合は1ファイルにまとめられます。Athenaの性質上複数ファイルに分かれていると読み込みが早くなる場合があるので、データ数が多い場合は分けることをお勧めします(例で100万: 1e6行にしています)。
)