やること
こんな感じのことをやる。
今回は「3, データ前処理」をやっていく。
【データ分析基礎】
1, データ収集(スクレイピング)
2, データの保存
3, データ前処理
4, データの可視化および考察
5, データに対しての結論および施策
ちなみに前回はこちら「1, データ収集(スクレイピング)」。
前回記事
動画で見たい人用リンク
上記スクレイピングで集めたデータを用いて、前処理を行っていく。
読んでない方は流れが把握しづらいと思うので、ざっくり前回の記事を読んでいただけるとよいかと。
作成背景
「python データ前処理」と検索しても、いっつも同じタイタニックやらのscikit-learnデータばかりで、
クソつまらんかったから、誰もやってないデータで、誰もやってないデータ前処理をやってみたかった。
環境
- python3.7.0
- jupyter notebook
- ビックカメラcsv
- jupyberコード
必要スキル&環境
- pythonの基礎構文は知っている
- pandasちょびっと知っている
- jupyter notebook or google colaboratory環境がある
1, データを観察する
■まずはcsvファイルをpandas dataframeとして読み込む。
まあ自分でデータ取ったから、内容は楽勝やで。
import pandas as pd
df = pd.read_csv("biccamera_all_laptop.csv")
df.head()
■行数を取得, カラム名を確認, nullの個数を確認する
通常データ見るまでわからんけど、nullの数もゼロなのをワイが事前に処理。
# 行数を取得
print(len(df))
# カラム名を確認
print(df.columns)
# nullの個数を確認する
print(df.isnull().sum())
■dataframeの情報を確認, カラムごとのユニーク数をカウント
info()も知っている。
ただ、ユニーク数は見てみると、titleがちょびっと重複してるなと。
makerは30社で、priceとpointの数が異なるなと。
事前にpoint見てて「ポイント(10%)」ってなってたから、
全部価格の10%かと思ってたけど、違うんかなと
なんて考えた。
# dataframeの情報を確認
print(df.info())
# カラムごとのユニーク数をカウント
print(df.nunique())
■各種value_counts()してみる
まあ、こんな感じか。
あんまり言うことないな(笑)
# 配達期日
print(df.terms.value_counts())
# 在庫情報
print(df.stock.value_counts())
# メーカー名
print(df.maker.value_counts())
2, 必要なデータを抽出する
■タイトルが怪しいので見てみる
for t in df.title:
print(t)
print(len(t))
print("*" * 100)
■全角半角入り混じってるから、統一させる関数作った
半角カタカナを全角にし、全角英数字を半角にする関数。
個人的によく使用する。
import re
import jctconv
def han2zen2han(string):
"""
半角カタカナを全角にし、
全角英数字を半角にする
:param string: string text
:return: string text
"""
string = jctconv.h2z(string, kana=True, digit=False, ascii=False)
string = jctconv.z2h(string, kana=False, digit=True, ascii=True)
return string
■タイトルから[XXXX/XXXX/]みたいなリスト取得。
一旦正規表現r"[.+?]"で[]を全部取得。
タイトルの中に複数個[]があるパターンもある。
で、ノートPCの画面サイズも正規表現で取る。
[]の中にサイズがあるものもあれば、無いものもある。
# Seriesで取得してみる
df.title.apply(get_spec_list)
# 1つ取り出して中を確認
df.title.apply(get_spec_list)[0]
関数は下記。
def get_spec_list(title):
"""
spec_list = 商品タイトルから[]を中身と一緒に抽出する
inch_list = 商品タイトルからPCの画面インチテキストを抽出する
l = spec_listから抽出したPCスペックをリストに入れ直す
:param title: string text
:return: list
"""
l = []
t = han2zen2han(title)
spec_list = re.findall(r"\[.+?\]", t)
inch_list = re.findall(r"(\d\d\.\d|\d\d|\d\..|\d)(インチ|型)", t)
inch = "".join(inch_list[0]) if inch_list else ""
for spec in spec_list:
specs = spec.replace("[", "").replace("]", "").replace(" ", "").replace("・", "/").replace(":", "").split("/")
for s in specs:
l.append(s)
if inch:
l.append(inch)
return list(set(l))
■もう書くのとスクショ貼り付けるの大変やから、このあたりにしとく。
とりあえず下の実行してみてほしい。
# PCスペックのベースとなるリストを抽出する
df["spec_list"] = df.title.apply(get_spec_list)
# CPUデータを取得
df["intel_cpu"] = df.spec_list.apply(get_intelcpu)
df["amd_cpu"] = df.spec_list.apply(lambda x: "".join([i for i in x if re.search(r"amd", i.lower())]))
# メモリデータ取得(int)
df["memory"] = df.spec_list.apply(get_memory)
# HDDデータ取得(int)
df["hdd"] = df.spec_list.apply(get_hdd)
# SSDデータ取得(int)
df["ssd"] = df.spec_list.apply(get_ssd)
# eMMCデータ取得(int)
df["emmc"] = df.spec_list.apply(get_emmc)
# インチ、型データ取得(float)
df["inch"] = df.spec_list.apply(get_inch)
# インチ、型データ取得(int)
df["int_inch"] = df.inch.astype("int")
# メーカー名取得(str)
df["new_maker"] = df.maker.apply(get_maker)
# PC価格を取得(int)
df["new_price"] = df.price.str.replace(r"\D", "").astype("int")
# PC購入時のポイントを取得(int)
df["new_point"] = df.point.str.replace(r"(ポイント|\n).*", "").str.replace(",", "").astype("int")
# PCの評価を取得(int)
df["new_ratings"] = df.ratings.str.replace(r"\D", "").astype("int")
# PCのタイトルの文字数を取得(int)
df["string_len"] = df.title.str.len()
# PCのタイトルの単語数を取得(int)
df["words_len"] = df.title.str.split().str.len()
最終こんな感じになる。
終わりに
動画としてに置いといたから、処理の流れを実際に見たい人はyoutubeで見て頂戴な。
コードを動かしているのを見たい方は上記リンクの「data processing 02」からどうぞ。
結構説明長いので、早送りおすすめ。