4. 表データとPandasを使いこなそう

今回は、データ分析と言えば、避けては通れないPandas の使い方を学び、 表データの操作を練習します。

4.1. Pandas とは

Pandas とは、表データを扱うPython モジュールで、表計算ソフト (Excel)やリレーショナルデータベースの操作を Python から手軽に行えるようにしてくれます。

次のようにpandasモジュールをインポートして使います。

[1]:
import pandas as pd

Pandas は、とても高機能です。

本講義では、Pandas でデータ分析をする必須の機能だけ紹介し、ハンズオン演習で体験します。

  • 暗記するものではありません。

  • どういうデータ処理や操作ができるか、覚えましょう。

  • 使うときは、Google 等で調べながら使ってください。

4.1.1. データの用意

Pandas の使い方に慣れるために、小さな練習用のデータを作成して、 そちらを使って演習していきます。

ファイル書き込み機能(%%file)を使って、Colab上でCSVファイル arashi.csvを作ります。

[2]:
%%file arashi.csv
名前,出身,生年,身長,血液型
相葉雅紀,千葉,1982,175,AB
松本潤,東京都,1983,172,A
二宮和也,東京都,1983,168,A
大野智,東京都,1980,166,A
櫻井翔,東京都,1982,171,A
Overwriting arashi.csv

データが間違っている?

一部間違っていると指摘をよく受けます。 どうぞ、各自でご自由に、ご修正して練習にお使いください。

CSV ファイルは、表計算ソフト(Excel)のファイルをデータ処理しやすく、カンマ区切り形式のテキストで出力したものです。当然、Excel 等の表計算ソフトで開いてみることができます。

68a2c49426094d7eafeca9dc59a60604

もうひとつ、あとから表データの結合をする練習で用いる junk.csv (わざと少し壊れたファイル)も作っておきましょう。

[3]:
%%file junk.csv
name,height,weight
大野智,166,52.0
相葉雅紀,176,58.0
二宮和也,168,52.0
松本潤,173,62.0
カビゴン,210,460.0
Overwriting junk.csv

Let’s try

ちゃんとarashi.csvが作成されているか、表計算ソフトで確認してみよう。

4.2. 基本操作

Pandas は、表データを効率よく操作できます。

Pandas 用語では、表データのことをデータフレーム(DataFrame)と呼びますが、本資料では表データと呼びます。

dataframe-fs8.png

覚えておこう:Pandas用語

  • カラム: 列方向のデータ

  • インデックス: 行方向のデータ

4.2.1. CSVファイルの読み込み

Pandas では、pd.read_csv()を用いると、CSVファイルから表データを読み込めます。

[4]:
data = pd.read_csv('arashi.csv')
data.head()  # 最初の5行のみ表示
[4]:
名前 出身 生年 身長 血液型
0 相葉雅紀 千葉 1982 175 AB
1 松本潤 東京都 1983 172 A
2 二宮和也 東京都 1983 168 A
3 大野智 東京都 1980 166 A
4 櫻井翔 東京都 1982 171 A

読み込んで表データは、dataという名前にしてあります。

表データへの操作は、data.head()のようにメソッドで操作します。

4.2.2. 属性名からカラム(列)を取り出す

Pandas では、属性ごとのデータ処理が多くなります。 まず、属性名'名前'のデータを取り出してみましょう。

[5]:
data['名前']
[5]:
0    相葉雅紀
1     松本潤
2    二宮和也
3     大野智
4     櫻井翔
Name: 名前, dtype: object

取り出した属性データは、Pythonの列(シーケンス)として、for文などで処理できます。

[6]:
for name in data['名前']:
  print(name)
相葉雅紀
松本潤
二宮和也
大野智
櫻井翔

4.2.3. 属性(列データ)の追加

新しい属性、つまり列データを追加してみましょう。

表データ中には、5人分のデータがあるため、リストとして5人分のデータを代入すると、 新しい属性を追加することができます。

例. 性別を追加する

[7]:
data['性別'] = ['男性', '男性', '男性', '男性', '男性']  # ['男性'] * 5

data #表示
[7]:
名前 出身 生年 身長 血液型 性別
0 相葉雅紀 千葉 1982 175 AB 男性
1 松本潤 東京都 1983 172 A 男性
2 二宮和也 東京都 1983 168 A 男性
3 大野智 東京都 1980 166 A 男性
4 櫻井翔 東京都 1982 171 A 男性

上級者向け: 列に数式を適用する

applyを使えば、各列データに関数やラムダ式を適用した列がえられます。

data['年齢'] = data['生年'].apply(lambda x: 2021 - x)

4.2.4. n行目のデータを取り出す

表データの列ごとへのアクセスは、.ilocプロパティを通して行ます。

[8]:
data.iloc[0]
[8]:
名前     相葉雅紀
出身       千葉
生年     1982
身長      175
血液型      AB
性別       男性
Name: 0, dtype: object
[9]:
for values in data.iloc[0]:
  print(values)
相葉雅紀
千葉
1982
175
AB
男性

4.2.5. セルの値

インデックスと属性の組み合わせで、表データをセルの値を指定して取り出すことができます。

[10]:
data.iloc[0]['出身']  # data['出身'][0]と書いてもよい
[10]:
'千葉'

4.2.6. 表データの出力

Pandas で操作した表データは、.to_csv()でCSVファイルに保存できます。

[11]:
data.to_csv('arashi2.csv', index=False)  #インデックスなしで出力
[12]:
!cat data.csv
名前,出身,生年,身長,血液型,性別
相葉雅紀,千葉,1982,175,AB,男性
松本潤,東京都,1983,172,A,男性
二宮和也,東京都,1983,168,A,男性
大野智,東京都,1980,166,A,男性
櫻井翔,東京都,1983,171,A,男性

4.3. リレーショナル代数

Pandas のリレーショナル代数の操作をみていきましょう。

データベース実習を履修している人は、SQLを思い出しながら試していきましょう。

リレーショナル代数って何?

SQLの元になったデータ操作を集合論をベースに定義した代数系です。 Pandas の操作を覚えるときは、Excel や SQL などの操作と対応付けながら、 マスターしていきましょう。

4.3.1. 選択(selection)

選択は、指定した条件に合う行を取り出します。データを抽出するフィルターの役割になります。

SELECT * FROM data WHERE '身長 >= 170'
[13]:
data[data['身長'] >= 170]
[13]:
名前 出身 生年 身長 血液型 性別
0 相葉雅紀 千葉 1982 175 AB 男性
1 松本潤 東京都 1983 172 A 男性
4 櫻井翔 東京都 1982 171 A 男性

複雑な条件は、.query()メソッドを用いて与えることもできます。

[14]:
data.query('身長 >= 170 and 血液型 == "A"')
[14]:
名前 出身 生年 身長 血液型 性別
1 松本潤 東京都 1983 172 A 男性
4 櫻井翔 東京都 1982 171 A 男性

4.3.2. 射影(projection)

射影(projection)は、表データから属性を限定した表データを返します。 Pandasでは、抽出したい属性名をリストにして渡します。

SQL例

SELECT 名前,生年,血液型 FROM data
[15]:
data[['名前', '生年', '血液型']]
[15]:
名前 生年 血液型
0 相葉雅紀 1982 AB
1 松本潤 1983 A
2 二宮和也 1983 A
3 大野智 1980 A
4 櫻井翔 1982 A

4.3.3. 表の連結

複数のファイルに入っている表データをまとめてひとつにしたいことがあります。

今度は、最初に作ったもう一つのCSVファイル junk.csvを読み込んで、連結してみます。

[16]:
data2 = pd.read_csv('junk.csv')
data2
[16]:
name height weight
0 大野智 166 52.0
1 相葉雅紀 176 58.0
2 二宮和也 168 52.0
3 松本潤 173 62.0
4 カビゴン 210 460.0

単純に縦方向に連結したいときは、pd.concat()を使って連結します。 (属性名が異なるので、綺麗につながりません)

[17]:
pd.concat([data, data2])
[17]:
名前 出身 生年 身長 血液型 性別 name height weight
0 相葉雅紀 千葉 1982.0 175.0 AB 男性 NaN NaN NaN
1 松本潤 東京都 1983.0 172.0 A 男性 NaN NaN NaN
2 二宮和也 東京都 1983.0 168.0 A 男性 NaN NaN NaN
3 大野智 東京都 1980.0 166.0 A 男性 NaN NaN NaN
4 櫻井翔 東京都 1982.0 171.0 A 男性 NaN NaN NaN
0 NaN NaN NaN NaN NaN NaN 大野智 166.0 52.0
1 NaN NaN NaN NaN NaN NaN 相葉雅紀 176.0 58.0
2 NaN NaN NaN NaN NaN NaN 二宮和也 168.0 52.0
3 NaN NaN NaN NaN NaN NaN 松本潤 173.0 62.0
4 NaN NaN NaN NaN NaN NaN カビゴン 210.0 460.0

横方向に連結したいときは、axis=1のオプションをつけます。

[18]:
pd.concat([data, data2], axis=1)  #横方向に連結
[18]:
名前 出身 生年 身長 血液型 性別 name height weight
0 相葉雅紀 千葉 1982 175 AB 男性 大野智 166 52.0
1 松本潤 東京都 1983 172 A 男性 相葉雅紀 176 58.0
2 二宮和也 東京都 1983 168 A 男性 二宮和也 168 52.0
3 大野智 東京都 1980 166 A 男性 松本潤 173 62.0
4 櫻井翔 東京都 1982 171 A 男性 カビゴン 210 460.0

4.3.4. 表データの結合(join)

表データの結合は、ふたつの表データのある属性をキーにして、キーが同じ値であれば一つの行にまとめる操作です。

Pandasでは、pd.merge()で結合します。

``名前``と``name``をキーにする

[19]:
pd.merge(data, data2, left_on='名前', right_on='name')

[19]:
名前 出身 生年 身長 血液型 性別 name height weight
0 相葉雅紀 千葉 1982 175 AB 男性 相葉雅紀 176 58.0
1 松本潤 東京都 1983 172 A 男性 松本潤 173 62.0
2 二宮和也 東京都 1983 168 A 男性 二宮和也 168 52.0
3 大野智 東京都 1980 166 A 男性 大野智 166 52.0

ふたつの表データは結合されましたが、データが一部消えてしまいました。 これは、Pandas では何も指定しなければ、一番条件の厳しい内部結合が用いられるためです。

結合の方法 * 内部結合 inner: 両方にキーが存在するとき結合 * 外部結合 outer: どちらか一方にキーが存在するとき結合 * 左外部結合 left: 左側にキーが存在するとき * 右外部結合 right: 右側にキーが存在するとき

leftが良さそうですが、outerで結合してみます。

[20]:
pd.merge(data, data2, left_on='名前', right_on='name', how='outer')
[20]:
名前 出身 生年 身長 血液型 性別 name height weight
0 相葉雅紀 千葉 1982.0 175.0 AB 男性 相葉雅紀 176.0 58.0
1 松本潤 東京都 1983.0 172.0 A 男性 松本潤 173.0 62.0
2 二宮和也 東京都 1983.0 168.0 A 男性 二宮和也 168.0 52.0
3 大野智 東京都 1980.0 166.0 A 男性 大野智 166.0 52.0
4 櫻井翔 東京都 1982.0 171.0 A 男性 NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN カビゴン 210.0 460.0

また、属性名が英語だったり、日本だったり不統一です。 少し整頓しておきましょう。

[21]:
# data, data2を外部結合した表データを新しく data とする
data = pd.merge(data, data2, left_on='名前', right_on='name', how='outer')

data.drop('name', axis=1, inplace=True)
data.drop('height', axis=1, inplace=True)
data.drop(5, axis=0, inplace=True)  #index=5を消す
data.rename(columns={'weight': '体重'}, inplace=True)

data
[21]:
名前 出身 生年 身長 血液型 性別 体重
0 相葉雅紀 千葉 1982.0 175.0 AB 男性 58.0
1 松本潤 東京都 1983.0 172.0 A 男性 62.0
2 二宮和也 東京都 1983.0 168.0 A 男性 52.0
3 大野智 東京都 1980.0 166.0 A 男性 52.0
4 櫻井翔 東京都 1982.0 171.0 A 男性 NaN

pandas の表操作は書き換えない

pandas の表操作は、新しい表データを返すようになっています。 だから、別の変数名で別の表データとして操作することもできます。

# 新しい表を data2 として操作する
data2 = data.drop('name', axis=1)

だから、同じ変数名で置き換えることもできます。

data = data.drop('name', axis=1)

データを直接、書き換えたいときは、inplace=Trueをつけます。

data.drop('name', axis=1, inplace=True)

Let’s try

Google で調べて、 dataのカラムの順番を名前   性別  出身  生年  身長  体重    血液型に変更してみよう。

(Google で調べて、操作できるようになれば、OKです。)

4.4. データ分析の準備

次回からPandas を用いて、より本格的なデータ分析を始めます。

4.4.1. 欠損値のチェック

世の中のデータは、データ値が欠けていることがあります。 今回の練習データでは、NaNと表示されている値が、欠損値になります。 データ件数が少ない場合は、目視でみつかる場合がありますが、 データ件数が多くなると、手作業で探すのは無理です。

欠損値をチェックすることが必要になります。

[22]:
data.isnull().sum()
[22]:
名前     0
出身     0
生年     0
身長     0
血液型    0
性別     0
体重     1
dtype: int64

欠損値が見つかったときは、 欠損値を処理するアプローチとしては:

  • dropna():データが欠損している行や列を削除する

  • fillna():データが欠損している要素を別の値で穴埋めする

どのように処理するかは、データ分析の目的によって異なります。 今回は、メンバーを消してしまったら、大変なことになりますので、 __欠損値の値を平均値で補完する__ことで対応してみます。

[23]:
data.fillna(data.mean(), inplace=True)
data
[23]:
名前 出身 生年 身長 血液型 性別 体重
0 相葉雅紀 千葉 1982.0 175.0 AB 男性 58.0
1 松本潤 東京都 1983.0 172.0 A 男性 62.0
2 二宮和也 東京都 1983.0 168.0 A 男性 52.0
3 大野智 東京都 1980.0 166.0 A 男性 52.0
4 櫻井翔 東京都 1982.0 171.0 A 男性 56.0

欠損値の補完

データ分析では、欠損値は何かの嫌がらせかと思うほど、頻繁に生じます。 色々な補完方法がありますので、適切な方法を選んでください。

data['体重'].fillna(50.0)                 # 体重の欠損値を50.0で穴埋め
data['体重'].fillna(data['体重'].mean())   # 体重の欠損値を体重の平均値で穴埋め
data['体重'].fillna(data['体重'].median()) # 体重の欠損値を体重の中央値で穴埋め
data['体重'].fillna(data['体重'].mode())   # 体重の欠損値を体重の最頻値で穴埋め

4.4.2. グループごとの集計

groupby() は、同じ値を持つデータをまとめて、統計処理を行いときに使います。

例. 血液型ごとに平均(mean)をとる

[24]:
data.groupby('血液型').mean()
[24]:
生年 身長 体重
血液型
A 1982.0 169.25 55.5
AB 1982.0 175.00 58.0

``describe()``: 基礎統計量を全てみたいとき

[29]:
data.groupby('血液型').describe()
[29]:
生年 身長 体重
count mean std min 25% 50% 75% max count mean ... 75% max count mean std min 25% 50% 75% max
血液型
A 4.0 1982.0 1.414214 1980.0 1981.5 1982.5 1983.0 1983.0 4.0 169.25 ... 171.25 172.0 4.0 55.5 4.725816 52.0 52.0 54.0 57.5 62.0
AB 1.0 1982.0 NaN 1982.0 1982.0 1982.0 1982.0 1982.0 1.0 175.00 ... 175.00 175.0 1.0 58.0 NaN 58.0 58.0 58.0 58.0 58.0

2 rows × 24 columns

groupby()は、グループごとに集計して操作するときに、重宝します。 ただし、返されるのはGroupByオブジェクトで表データとして使えません。

ピボットテーブルを用いると、集計結果を表データに変換して取り出せるようになります。

[25]:
pd.pivot_table(data, index="血液型")
[25]:
体重 生年 身長
血液型
A 55.5 1982.0 169.25
AB 58.0 1982.0 175.00

ピボットテーブルとクロス集計

ピボットテーブルは、クロス集計に使われる便利ツールです。

  • index: 縦軸に展開するカラムを指定

  • columns: 横軸に展開するカラムを指定

  • values: 集約する値カラムを指定

  • aggfunc: 集約方法を指定

ぜひ使えるようになりたいところですが、今回のサンプルはデータ件数が少なすぎます。 余力がある人は、次の時系列データで練習してみてください。

4.5. 時系列データ(★)

時系列データとは、時間の順番に並んだデータです。 コンピュータが記録するデータ(ログ)は、時系列データになっていることが多く、 データ分析を始める前に理解しやすい形に集計しなおす必要があります。

この節は、Pandas 初心者は、スキップして構いません。

時系列データは、データサイエンスの前処理で重要なデータ形式です。

しかし、初めて Pandas を習ったような場合は、 内容が多すぎて理解が追いつかなくなる可能性があります。 (スキップしてもらって、コースワークに進んでもらって構いません。)

データの入手

UNIXコマンド wgetで以下のURLから取り寄せてください。

!wget https://KuramitsuLab.github.io/data/elearn2018.csv
[30]:
data = pd.read_csv('elearn2018.csv')
data.head()
[30]:
name date problem point
0 Victoria 2018/5/2 2:35 1 1
1 Victoria 2018/5/2 2:46 2 1
2 Victoria 2018/5/2 2:49 3 1
3 Victoria 2018/5/2 2:53 4 1
4 Victoria 2018/5/2 3:12 5 1

データの内容は、E-ラーニング教材の学習ログです。

  • 解答者(name)

  • 解答した時間(date)

  • 問題番号(problem)

  • 得点(point)

解答者一覧と回答数

解答者ごとの回答数を調べてみましょう。

[53]:
data['name'].value_counts()
[53]:
Chloe       220
Victoria    164
Zoe         162
Maria       138
Adalynn      90
Name: name, dtype: int64

4.5.1. 日付

学習ログの日付は、文字列として記録されています。 このまま処理しても構いませんが、扱いやすいようにpandas の日付データに変換しておきます。

[32]:
data['date'] = pd.to_datetime(data['date'])
data.head()
[32]:
name date problem point
0 Victoria 2018-05-02 02:35:00 1 1
1 Victoria 2018-05-02 02:46:00 2 1
2 Victoria 2018-05-02 02:49:00 3 1
3 Victoria 2018-05-02 02:53:00 4 1
4 Victoria 2018-05-02 03:12:00 5 1

すると、日付はメソッド操作で様々な値に変換しやすくなります。

[33]:
print('日付', data['date'][0])
print('年', data['date'][0].year)
print('エポック秒', int(data['date'][0].timestamp()))
日付 2018-05-02 02:35:00
年 2018
エポック秒 1525228500.0

エポック秒とは、UNIX上で使われる1970年1月1日を起点にした秒です。 エポック秒に変換すると、整数値として、日付が処理しやすくなります。 エポック秒に変換し、新しいカラムepochを作っておきましょう。

[34]:
data['epoch'] = data['date'].map(pd.Timestamp.timestamp).astype(int)
data
[34]:
name date problem point epoch
0 Victoria 2018-05-02 02:35:00 1 1 1525228500
1 Victoria 2018-05-02 02:46:00 2 1 1525229160
2 Victoria 2018-05-02 02:49:00 3 1 1525229340
3 Victoria 2018-05-02 02:53:00 4 1 1525229580
4 Victoria 2018-05-02 03:12:00 5 1 1525230720
... ... ... ... ... ...
769 Chloe 2018-09-09 12:01:00 187 1 1536494460
770 Chloe 2018-09-09 12:14:00 166 1 1536495240
771 Chloe 2018-09-17 10:32:00 132 1 1537180320
772 Chloe 2018-09-17 10:35:00 133 0 1537180500
773 Chloe 2018-09-17 10:37:00 132 1 1537180620

774 rows × 5 columns

ここから、2018年5月1日を起点に、一週間ごとにデータを区切って、各週ごとの学習状況をみてみたいと思います。

2018年5月1日のエポック秒を調べる

[35]:
import datetime
import time
d = datetime.datetime(2018, 5, 1, 0, 0, 0) # 2018/05/01 のエポック秒
int(time.mktime(d.timetuple()))
[35]:
1525100400

一週間の秒数から、区切りの境界になるエポック秒をリスト化します。

[41]:
epoch_of_week = 7 * 24 * 60 * 60
bins = [1525132800 + i * epoch_of_week for i in range(0, 21)]
print(bins)

[1525132800, 1525737600, 1526342400, 1526947200, 1527552000, 1528156800, 1528761600, 1529366400, 1529971200, 1530576000, 1531180800, 1531785600, 1532390400, 1532995200, 1533600000, 1534204800, 1534809600, 1535414400, 1536019200, 1536624000, 1537228800]

ビン分割(ビニング処理)

連続値を任意の境界値で区切りカテゴリ分けして離散値に変換する処理のこと

Pandasでは、pd.cut()でビン分割します。ラベルは、第1週を1とします。

[43]:
data['week'] = pd.cut(data['epoch'], bins, labels=list(range(1,21))).astype(int)
data
[43]:
name date problem point epoch week
769 Chloe 2018-09-09 12:01:00 187 1 1536494460 19
770 Chloe 2018-09-09 12:14:00 166 1 1536495240 19
771 Chloe 2018-09-17 10:32:00 132 1 1537180320 20
772 Chloe 2018-09-17 10:35:00 133 0 1537180500 20
773 Chloe 2018-09-17 10:37:00 132 1 1537180620 20

4.5.2. クロス集計

週単位でビン分割できたので、各週ごとの集計ができるようになりました。

週ごとの得点集計

[49]:
data.groupby('week')['point'].sum()
[49]:
week
1     147
2     108
3      22
4      25
5      17
6      16
7      28
8      15
9       9
10     12
11     10
12     15
13      8
14     18
15      8
16     28
17      3
19      3
20      2
Name: point, dtype: int64

ピボット表を用いると横軸も指定できます。

各週ごとに各個人の得点集計

[51]:
pd.pivot_table(data, index="week", columns="name", values="point", aggfunc=sum)
[51]:
name Adalynn Chloe Maria Victoria Zoe
week
1 3.0 32.0 27.0 67.0 18.0
2 4.0 15.0 19.0 43.0 27.0
3 6.0 5.0 3.0 3.0 5.0
4 1.0 13.0 4.0 6.0 1.0
5 4.0 9.0 2.0 NaN 2.0
6 3.0 2.0 1.0 NaN 10.0
7 3.0 11.0 3.0 NaN 11.0
8 3.0 2.0 4.0 NaN 6.0
9 4.0 1.0 NaN NaN 4.0
10 4.0 7.0 NaN NaN 1.0
11 4.0 1.0 3.0 NaN 2.0
12 5.0 3.0 2.0 4.0 1.0
13 5.0 1.0 NaN NaN 2.0
14 15.0 0.0 0.0 0.0 3.0
15 4.0 4.0 NaN NaN NaN
16 1.0 10.0 7.0 NaN 10.0
17 NaN 3.0 NaN NaN NaN
19 NaN 3.0 NaN NaN NaN
20 NaN 2.0 NaN NaN NaN

軸を変えてみましょう。 縦軸を個人ごとに変更し、横軸に各問題ごとの解答状況を並べてみます。

[52]:
pd.pivot_table(data, index='name', columns='problem', values='point', aggfunc=max)
[52]:
problem 1 2 3 4 5 6 7 8 9 10 ... 122 125 132 133 137 151 162 163 166 187
name
Adalynn 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Chloe 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... NaN 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0
Maria 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Victoria 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Zoe 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 ... 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 117 columns

少し早足でしたが、時系列データを参考にクロス集計を試してみました。 パラメータを変更しながら、どのように変わるかみて、理解を深めてください。

4.6. コースワーク

コースワークは、pandasを使ったデータ操作の練習です。

演習(BMI.CSV)

野球選手(B)、サッカー選手(F)、相撲(W)に関するCSVファイルをまとめ、 次の属性からなるCSVファイルにしよう。

名前    身長    体重    職業    BMI
  1. 職業は、野球選手B、サッカーF、相撲Wとする

  2. BMI身長体重から計算する

  3. 身長の高い順にソートして、bmi.csvとして保存する

  4. 各職業ごとに、身長体重の分布図を描画する

  5. 各職業ごとにグループ集約し、身長と体重の統計量を求める

データの入手先

鈴木 雅也、渡辺 将人、井上 史斗. 「数式をプログラムするってつまりこういうこと」より、公開データを使わせてもらいます。

データをダウンロードするコマンド

!wget https://raw.githubusercontent.com/massongit/math-program-book/master/9_data/サッカー/Jリーグ選手身長体重.csv
!wget https://raw.githubusercontent.com/massongit/math-program-book/master/9_data/プロ野球/プロ野球選手身長体重.csv
!wget https://raw.githubusercontent.com/massongit/math-program-book/master/9_data/相撲/力士身長体重.csv