投資のためのデータサイエンス

個人の投資活動に役立つデータ分析にまつわる話題を綴ります。

PythonによるECカタログデータの分析小技集(上)

一部のECサイトでは、販売商品のカタログデータをAPIにより取得することができます。このようなデータには、商品名、商品の補足説明、価格などの情報が含まれています。ここでは、このようなECサイトのカタログデータを処理・分析するためのpythonの小技をまとめました。ここで用いるデータは「楽天ブックス書籍検索API」を利用してダウンロードした書籍情報データです。
まず必要なライブラリを読み込み、データを保存先からロードします。

# ライブラリのインポート
import numpy as np
import pandas as pd
import re
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font=['IPAexGothic'])
# parquetファイルからロード
df01 = pd.read_parquet('rakuten_books.parquet')
# 列を絞り込む
focus_cols=['title','subTitle','seriesName','contents','author','publisherName','size',\
	'itemCaption','salesDate','itemPrice','reviewCount','reviewAverage']
df1 = df01.loc[:,focus_cols]

テキスト項目の文字列検索
まず、テキスト情報からあるキーワードを含む行を抽出するケースを考えます。pandasのSeries.str.contains()を用います。これにより、指定した文字列を含む行のみを取り出すことができます。またこのコードでは、Jupyter Notebookの出力イメージをそのまま画像ファイルに変換するdataframe_imageライブラリを用いています。

import dataframe_image as dfi
# テキスト項目で特定の文字列を検索する
col_name = 'title'
ch_kw = '資産'
df201 = df1[df1[col_name].str.contains(ch_kw)]
dfi.export(df201,'kensaku_sisan.png')

以下のような検索結果が得られます。
f:id:nicjps230:20210709161416p:plain
次に、2つのキーワードについて、その両方を含む行を取り出したい(and条件)場合は、一つのキーワードで絞りこんだデータフレームに対してもう一つのキーワードでさらに絞りこみをかけることでできます。【注】一つの命令文にブール演算を埋め込んで検索することは、下に記載したquery()メソッドではできますが、それ以外ではエラーが出るためここでは避けています。

# テキスト項目で特定の複数の文字列をand検索する
col_name = 'itemCaption'
ch_kw1 = '成功'; ch_kw2 = '金'
df202 = df1[df1[col_name].str.contains(ch_kw1)]
df203 = df202[df202[col_name].str.contains(ch_kw2)]
print('該当するデータ件数 = ',len(df203))

一方、2つのキーワードのどちらかが含まれる行を抽出したい(or条件)場合は、元のデータフレームを個別のキーワードで絞りこんだ結果を縦結合することでできます。これは検索対象の列が異なる場合にも応用できます。どちらかの検索結果がゼロ行でも特に問題はありません。

# テキスト項目で特定の複数の文字列をor検索する
col_name = 'title'
ch_kw1 = '資産'; ch_kw2 = '財産'
df204 = df1[df1[col_name].str.contains(ch_kw1)]
df205 = df1[df1[col_name].str.contains(ch_kw2)]
df206 = pd.concat([df204,df205])
print('該当するデータ件数 = ',len(df206))

特定の数値項目で条件検索する
今度は数値データが入った列について、ある条件を満たす行を取り出すことを考えます。例えば値がゼロより大きい行を抽出するには、df[df['列名']>0]とする書き方と、df.query('列名>0')という書き方があります。

# 数値変数で条件検索する
ch_col='reviewCount'; s_val=500
df31 = df1[df1[ch_col] >= s_val]
dfi.export(df31,'top_review_no.png')
#数値検索の別の記述法
ch_col='reviewCount'; s_val=500
df32 = df1.query('{0} >= @s_val'.format(ch_col))
dfi.export(df32,'top_review_no2.png')

結果は以下のようになります。
f:id:nicjps230:20210719000425p:plain
特定の列項目が空でないケースを抽出する
次に、テキストからなる特定の列項目が空でないケースを抽出する方法を考えます。テキスト情報で何も書かれていないのは空文字列('')なので、まず空文字列を欠損値(NaN)に置き換えます。その後で欠損値を含む行を削除します。

# 列名を指定する
col_name = 'contents'
# データフレームをコピーする
df211 = df1.copy()
#空白をまずNaNに置き換え
df211[col_name].replace('', np.nan, inplace=True)
#Nanを削除 inplace=Trueでdfが上書きされる。
df211.dropna(subset=[col_name], inplace=True)
print('該当するデータ件数 = ',len(df211))

(下巻へ続く)