ねこすたっと

ねこの気持ちと統計について悩む筆者の備忘録的ページ。

チュートリアル拾い読み (9):Pandas公式チュートリアル (4/7) [Python]

Rもたいして使いこなせてないのにPythonの勉強を始めてみました。色々と素晴らしいチュートリアルはありそうですが、目移りしてしまうので公式チュートリアルを拾い読みしていきます。

NumPyが終わってPandasに入っています。導入版(Intro to pandas)・簡易版(10 minutes to pandas)は物足りなず、本格版(User guideのIntro to data structures以降)は読みきれなかったので、チートシート(PDF)を中心に読んでいきます。

前回:

necostat.hatenablog.jp

前回からデータテーブルの一部の行(= 観察単位, observation)や列(= 変数, variable)、あるいは両者が交差する要素にアクセスする方法を確認しています。今回は列単位の抽出と、ついでに列に対する操作を確認します。

最初にPandasライブラリと、前回使用したirisデータセットを読み込んでおきます。

import pandas as pd
df = pd.read_csv("iris.csv")

列を抽出する

列名を指定して抽出する

[] の中に列名を書きます。複数の場合はリストで渡します。

df[["sepal.length", "sepal.width"]]

# 出力:
     sepal.length  sepal.width
0             5.1          3.5
1             4.9          3.0
2             4.7          3.2
3             4.6          3.1
4             5.0          3.6
..            ...          ...
145           6.7          3.0
146           6.3          2.5
147           6.5          3.0
148           6.2          3.4
149           5.9          3.0

[150 rows x 2 columns]

条件に合致する列を抽出する

.filter()を使います(Rでは行の部分抽出に使う関数なので間違えそうです)。列の名前に基づいた条件で選んでくることになるので、使いこなそうとすると正規表現(文字列のパターンを表すための決まりごと)を学ぶ必要がありそうです。

df.filter(regex="abc")とすれば、変数名にabcを含んでいるものだけが取り出されます。

例えば、irisデータの中で"al"が含まれるものは、

df.filter(regex="al")
# 出力:
     sepal.length  sepal.width  petal.length  petal.width
0             5.1          3.5           1.4          0.2
1             4.9          3.0           1.4          0.2
2             4.7          3.2           1.3          0.2
3             4.6          3.1           1.5          0.2
4             5.0          3.6           1.4          0.2
..            ...          ...           ...          ...
145           6.7          3.0           5.2          2.3
146           6.3          2.5           5.0          1.9
147           6.5          3.0           5.2          2.0
148           6.2          3.4           5.4          2.3
149           5.9          3.0           5.1          1.8

となります。

その他、頻用しそうなものとして、

  • ^abc:名前がabcで始まるもの
  • xyz$:名前がxyzで終わるもの

は覚えておきます。 もう少し複雑なもの(?!や記号のバックエスケープなど)はまた別の機会に...。

列を除外する

残す変数を選ぶのではなく、削除したい変数を指定する場合は、.drop()を使います。

df.drop("sepal.length", axis=1)

列に対する操作なのでaxis=1が必要です。インデックス名を使って行を削除するときはaxis=0とします。

.drop()は正規表現を直接受け付けてくれないようです。

列名を変更する

.rename()を使います。columns={ }のカッコ内に、"旧名":"新名"の要領で書きます。

df.rename(columns={"sepal.length":"S.L",
                   "sepal.width":"S.W",
                   "petal.length":"P.L",
                   "petal.width":"P.W"})
# 出力:
     S.L  S.W  P.L  P.W    variety
0    5.1  3.5  1.4  0.2     Setosa
1    4.9  3.0  1.4  0.2     Setosa
2    4.7  3.2  1.3  0.2     Setosa
3    4.6  3.1  1.5  0.2     Setosa
4    5.0  3.6  1.4  0.2     Setosa
..   ...  ...  ...  ...        ...
145  6.7  3.0  5.2  2.3  Virginica
146  6.3  2.5  5.0  1.9  Virginica
147  6.5  3.0  5.2  2.0  Virginica
148  6.2  3.4  5.4  2.3  Virginica
149  5.9  3.0  5.1  1.8  Virginica

列を作成する

1つずつ作成する

既存の変数をもとに、新たな変数を作成する場合は、df[]を使います。例えば、sepal.lengthsepal.widthの積を保持するsepal.areaという変数を作成する場合は次のように書きます。

df["sepal.area"] = df["sepal.length"]*df["sepal.width"]
# 出力: 
   sepal.length  sepal.width  petal.length  petal.width variety  sepal.area
0           5.1          3.5           1.4          0.2  Setosa       17.85
1           4.9          3.0           1.4          0.2  Setosa       14.70
2           4.7          3.2           1.3          0.2  Setosa       15.04
3           4.6          3.1           1.5          0.2  Setosa       14.26
4           5.0          3.6           1.4          0.2  Setosa       18.00

複数まとめて作成する

.assign()を使って、複数の列を一度に作成できます。

df = df.assign(sepal_area = df["sepal.length"]*df["sepal.width"],
               petal_area = df["petal.length"]*df["petal.width"])

作成した変数を保持するためにdfに再代入しました。

この方法だとピリオドが入った変数名で作成することができません(引数を辞書形式で渡せば出来るみたいです)。

おわりに

今回学んだこと:

  • 列の抽出・除外
  • 列名変更
  • 列の作成

チュートリアルは読んだけど取り上げなかったもの:

  • 正規表現
  • .assign()メソッドの中でラムダ式で変数を定義する方法

この2つはチートシート拾い読みで扱うには大きすぎます。

  • .clip()を使って指定した上下端でトリミングをする方法
  • .qcut()を使って連続変数をカテゴリー化する方法

この2つは知ってると便利そうだなと思いました。

次回:

necostat.hatenablog.jp