Top > Python

【データアナリスト向け】Python Data Cooking ハンズオン資料



2017/9に行った、Python初心者へのハンズオンレクチャー用の資料です。
広告業界の方向けに、サンプルデータは上場している広告関連企業の株価データにしました。

※データのダウンロードはこちらから。
※スマホから見るとOutputエリアが見にくくなっているようです。ご容赦ください。
※関連ページ:Python関連のオススメの本
※ハンズオンをご希望の方はご連絡ください。:support@lixnect.com

Python ハンズオン

Author:Lixnect
Date:2017/9/18

1.データ読み込み


Pandasで読み込める主な構造化データフォーマット

テキストファイル

  • CSV
  • TSV
  • JSON

ツール類

  • Excel
  • Spreadsheet
  • TreasureData
  • BigQuery
  • MySQL
  • PostgreSQL

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html

In [1]:
import os
import pandas as pd

# Windows home path
# path = os.getenv("HOMEDRIVE") + os.getenv("HOMEPATH") + "\\downloads/"

# Mac home path
path = os.path.expanduser("~/") + "downloads/"
In [2]:
df = pd.read_csv(path+"pyhandson.csv", header=0, index_col="date", parse_dates=["date"], encoding="shift-jis")
df.sort_index().head()
Out[2]:
市場 コード 銘柄名 始値 高値 安値 終値 出来高 売買代金
date
2017-01-04 JQスタンダード 4293-T セプテーニHD 400.0 408.0 399.0 406.0 1041400 421539200
2017-01-04 東証2部 6534-T DACHD 889.0 893.0 875.0 893.0 96200 85186500
2017-01-04 東証1部 2389-T オプトHD 720.0 728.0 716.0 727.0 42300 30599100
2017-01-04 東証1部 2433-T 博報堂DY 1444.0 1470.0 1444.0 1469.0 751300 1098286500
2017-01-04 東証1部 4751-T サイバエージ 2910.0 2986.0 2880.0 2930.0 1570300 4609883900
In [3]:
print(df.shape)
print("-------------------------------")
df.info()
print("-------------------------------")
df.describe()
(1056, 9)
-------------------------------
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1056 entries, 2017-01-04 to 2017-09-15
Data columns (total 9 columns):
市場      1056 non-null object
コード     1056 non-null object
銘柄名     1056 non-null object
始値      1056 non-null float64
高値      1056 non-null float64
安値      1056 non-null float64
終値      1056 non-null float64
出来高     1056 non-null int64
売買代金    1056 non-null int64
dtypes: float64(4), int64(2), object(3)
memory usage: 82.5+ KB
-------------------------------
Out[3]:
始値 高値 安値 終値 出来高 売買代金
count 1056.000000 1056.000000 1056.000000 1056.000000 1.056000e+03 1.056000e+03
mean 2214.230114 2240.868371 2189.919508 2215.863636 7.804953e+05 1.951004e+09
std 1783.760550 1798.767147 1769.755177 1783.563474 7.094195e+05 2.464744e+09
min 279.000000 283.000000 274.000000 279.000000 2.890000e+04 2.102900e+07
25% 1033.750000 1063.750000 1014.750000 1045.500000 3.170500e+05 3.252704e+08
50% 1461.000000 1478.500000 1443.000000 1462.000000 6.678500e+05 7.541591e+08
75% 3396.250000 3446.250000 3361.250000 3400.000000 1.018925e+06 3.206171e+09
max 6550.000000 6550.000000 6460.000000 6530.000000 1.153690e+07 2.210056e+10

2.データ集計


主な集計内容

  • フィルター(文字、数値)
  • サマリ(groupby, pivot_table)
  • 結合(dict、join、merge、append)
  • 関数処理

行列フィルター:名称

In [4]:
# カラムのみ
df[["終値","出来高"]]

# インデックス
df.loc["2017-09-04":"2017-09-07", :]

# 両方
df.loc["2017-09-04":"2017-09-07", ["終値","出来高"]]
Out[4]:
0

行列フィルター:行列番号

In [5]:
df.iloc[:3, 1:4]
Out[5]:
コード 銘柄名 始値
date
2017-01-04 4293-T セプテーニHD 400.0
2017-01-05 4293-T セプテーニHD 408.0
2017-01-06 4293-T セプテーニHD 410.0

フィルター:文字

In [6]:
# 完全一致
df[df["銘柄名"] == "電通"].head()
Out[6]:
市場 コード 銘柄名 始値 高値 安値 終値 出来高 売買代金
date
2017-01-04 東証1部 4324-T 電通 5470.0 5560.0 5450.0 5540.0 1143200 6314079000
2017-01-05 東証1部 4324-T 電通 5520.0 5570.0 5500.0 5520.0 963000 5320135000
2017-01-06 東証1部 4324-T 電通 5550.0 5700.0 5540.0 5640.0 1335500 7524855000
2017-01-10 東証1部 4324-T 電通 5690.0 5780.0 5650.0 5710.0 1924100 10985764000
2017-01-11 東証1部 4324-T 電通 5700.0 5740.0 5660.0 5700.0 1165800 6647574000
In [7]:
# 部分一致
df[df["銘柄名"].str.contains("電|博", na=False)].sort_index().head()
Out[7]:
市場 コード 銘柄名 始値 高値 安値 終値 出来高 売買代金
date
2017-01-04 東証1部 4324-T 電通 5470.0 5560.0 5450.0 5540.0 1143200 6314079000
2017-01-04 東証1部 2433-T 博報堂DY 1444.0 1470.0 1444.0 1469.0 751300 1098286500
2017-01-05 東証1部 2433-T 博報堂DY 1465.0 1483.0 1463.0 1476.0 610000 899361400
2017-01-05 東証1部 4324-T 電通 5520.0 5570.0 5500.0 5520.0 963000 5320135000
2017-01-06 東証1部 4324-T 電通 5550.0 5700.0 5540.0 5640.0 1335500 7524855000

フィルター:数値

In [8]:
df[df["出来高"] >= 10000000]
Out[8]:
市場 コード 銘柄名 始値 高値 安値 終値 出来高 売買代金
date
2017-05-02 JQスタンダード 4293-T セプテーニHD 330.0 360.0 328.0 351.0 11536900 3967855900

サマリ:groupby

In [9]:
df.groupby(["市場","銘柄名"]).mean()[["出来高","売買代金"]]#/10000
Out[9]:
出来高 売買代金
市場 銘柄名
JQスタンダード セプテーニHD 1.274244e+06 4.511244e+08
東証1部 オプトHD 2.458642e+05 3.033046e+08
サイバエージ 1.126185e+06 3.816627e+09
博報堂DY 6.738392e+05 9.697978e+08
電通 1.022355e+06 5.683027e+09
東証2部 DACHD 3.404841e+05 4.821408e+08

サマリ:pivot_table

In [10]:
df.pivot_table("売買代金",
              index="date",
              columns="銘柄名",
              aggfunc='sum').head()
Out[10]:
銘柄名 DACHD オプトHD サイバエージ セプテーニHD 博報堂DY 電通
date
2017-01-04 85186500 30599100 4609883900 421539200 1098286500 6314079000
2017-01-05 168625400 21029000 2926239900 415126300 899361400 5320135000
2017-01-06 86879600 51603900 3242302700 721677200 865750700 7524855000
2017-01-10 110762900 94441600 3015419000 661797500 1133268900 10985764000
2017-01-11 169643800 52870200 1966611700 612832900 891865700 6647574000

結合:dict

In [11]:
cls_dict = {"DACHD":0, "オプトHD":0,"サイバエージ":0, "セプテーニHD":0, "博報堂DY":1,"電通":1}
df["cls"] = df["銘柄名"].map(cls_dict)
df.groupby(["cls", "銘柄名"]).mean()
Out[11]:
始値 高値 安値 終値 出来高 売買代金
cls 銘柄名
0 DACHD 1380.352273 1410.573864 1355.159091 1385.511364 3.404841e+05 4.821408e+08
オプトHD 1158.875000 1178.460227 1138.022727 1158.500000 2.458642e+05 3.033046e+08
サイバエージ 3382.801136 3427.562500 3347.852273 3390.801136 1.126185e+06 3.816627e+09
セプテーニHD 350.250000 355.801136 345.386364 350.630682 1.274244e+06 4.511244e+08
1 博報堂DY 1436.397727 1447.272727 1424.829545 1435.704545 6.738392e+05 9.697978e+08
電通 5576.704545 5625.539773 5528.267045 5574.034091 1.022355e+06 5.683027e+09

結合:join

省略(紐つけるDataFrame側のIndexがKey)

結合:merge

省略(任意のKeyを設定可能)

結合:append

省略(縦結合)

関数処理

In [12]:
# 1列による処理(df["売買代金(単位:万)"])
df["売買代金"].apply(lambda x:x/10000).head()
Out[12]:
date
2017-01-04    42153.92
2017-01-05    41512.63
2017-01-06    72167.72
2017-01-10    66179.75
2017-01-11    61283.29
Name: 売買代金, dtype: float64
In [13]:
# 複数列による処理(df["終値/始値"])
df.apply(lambda row: row["終値"]/row["始値"], axis=1).head()
Out[13]:
date
2017-01-04    1.015000
2017-01-05    1.004902
2017-01-06    1.053659
2017-01-10    0.967890
2017-01-11    0.948718
dtype: float64
In [14]:
%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
from pandas_highcharts.display import display_charts

Pandas Plot

pandas直結で利便性が高い

In [15]:
temp_df = df[df["銘柄名"].str.contains("DAC|博報堂|電通",na=False)]
temp_df = temp_df.pivot_table("出来高",index=temp_df.index, columns="銘柄名").rename(columns={
    "博報堂DY":"Hakuhodo", "電通":"dentsu"})
temp_df.plot(kind='hist', alpha=0.5, bins=50, xlim=[0, 1600000])
plt.show()

matplotlib+seaborn

多様なチャートパターンが表現可能。ヒートマップが良い。

In [16]:
sns.pairplot(temp_df)
plt.show()
In [17]:
# 前日比ヒートマップ
temp_df = (temp_df / temp_df.shift(1))-1
temp_df.index = temp_df.index.astype(str)
plt.subplots(figsize=(7, 10))
sns.set_context("talk")
ax = sns.heatmap(temp_df.iloc[-5:,:].applymap(lambda x:round(x,2)),
                 vmin=-3, vmax=3, square=True, annot=True, linewidths=.5, fmt='g')
plt.show()

Highcharts

美しい。インタラクティブなチャート。

In [18]:
df_pvt = df.pivot_table("終値",index=df.index, columns="銘柄名")
for n in set(df["銘柄名"]):
    df_pvt[n] = df_pvt[n] / df_pvt[n].iloc[0]
display_charts(df_pvt, kind="line", title="広告銘柄-年初来上昇率")

4.データ分析


主な分析・モデリングライブラリと特徴

  • scipy.stats:統計分布
  • statsmodels:線形回帰/モデリング
  • sklearn:機械学習全般
  • pymc:MCMC

ここから先は次回!


  • 関連ページ:Python関連のオススメの本
  • ハンズオンご希望の方やご不明点などございましたら、ご連絡ください :support@lixnect.com


Ads by Google