ねこすたっと

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

チュートリアル拾い読み (8):Pandas公式チュートリアル (3/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")

先頭・末尾の行を抽出する

先頭を取り出すには.head()、末尾を取り出すには.tail()というメソッドを使います。取り出したい行数を指定できます。

df.head(n=3)
# 出力:
   sepal.length  sepal.width  petal.length  petal.width 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

ランダムに行を抽出する

.sample()でランダムに行を抽出します。 使う状況はデータが大きすぎるので一部でお試ししたいときなどでしょうか。

抽出する個数か割合のどちらかを指定します。

  • n:抽出する個数を指定
  • frac:元データに対する割合を指定

その他の引数として、

  • random_state:乱数シードを指定
  • replace = True:復元抽出(同じものを2回以上抽出可)をしたいとき

などが指定できます。

df.sample(n=3, random_state=1234)
# 出力:
     sepal.length  sepal.width  petal.length  petal.width     variety
91            6.1          3.0           4.6          1.4  Versicolor
63            6.1          2.9           4.7          1.4  Versicolor
103           6.3          2.9           5.6          1.8   Virginica

指定した列について最大・最小の行を抽出する

.nlargest()で最大の行を、.nsmallest()で最小の行を抽出します。 指定する引数は以下のとおり。

  • n:抽出する個数(割合は不可)
  • columns:対象の列
df.nlargest(n=3, columns="sepal.length")
# 出力:
     sepal.length  sepal.width  petal.length  petal.width    variety
131           7.9          3.8           6.4          2.0  Virginica
117           7.7          3.8           6.7          2.2  Virginica
118           7.7          2.6           6.9          2.3  Virginica

指定した列にもとづいて行を並べ替える

部分抽出ではないですが、.sort_values()を使えば同じことができるのでここで取り上げます。

.sort_values()に大小判定の基準にする変数名を渡します。昇順のときはascending=True、降順のときはascending=Falseとします。

.nlargest()sepal.lengthが大きいもの3つを取り出したいときは、

df.sort_values("sepal.length", ascending=False).head(n=3)

とすれば前述と同じ結果が得られます。

余談ですが、上記のようにメソッドを繋いで書いていけるのは便利ですね。"Method Chaining"と呼ぶみたいです。

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

.query()を使います。使い方の注意は次のとおり。

  • カッコの中の条件は、全体を引用符で囲む
  • 変数名にスペースやアンダースコア以外の句読点(.,-,:,^,@など)が含まれているときはバックティック(``)で囲む
df.query("`sepal.length` > 7 & variety != 'Versicolor'")

条件を組み合わせるとき、それぞれの条件をカッコで囲む必要はないみたいですが、カッコをつけておく方が見やすい気がします。

# 出力:
     sepal.length  sepal.width  petal.length  petal.width    variety
102           7.1          3.0           5.9          2.1  Virginica
105           7.6          3.0           6.6          2.1  Virginica
107           7.3          2.9           6.3          1.8  Virginica
109           7.2          3.6           6.1          2.5  Virginica
117           7.7          3.8           6.7          2.2  Virginica
# 以下省略

条件式の中でデータフレーム外の変数を用いたい場合は@を使います。例えば、threshという名前で条件の基準を保持した場合、

thresh = 7
df.query("`sepal.length` > @thresh")

とすれば、sepal.length > 7と同じになります(出力は省略)。

.query()についてはAPIリファレンスを読みました。

pandas.pydata.org

重複している行を除く

.drop_duplicates()を使って、重複している行を除いて一意(unique)な行を抽出します。

df = pd.DataFrame(
    {"a":[10,20,10],
     "b":[40,50,40],
     "c":[70,80,70]},
    index = [1,2,3]
)

1行目と3行目が重複しています。

df.drop_duplicates()

# 出力:
    a   b   c
1  10  40  70
2  20  50  80

重複しているうち、最初に登場する1行目だけが残っています。

おわりに

今回学んだこと:

  • 条件に合致した行の抽出方法
  • Method chainingについて

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

  • 条件式の書き方

次回:

necostat.hatenablog.jp