Pandas プログラミング

【Pandas】条件で要素を取り出す方法【Dr. Python#6】

icon
historoid

こんにちには。@historoid1です。

今回は、自分が与えた条件で要素を取り出す方法を紹介します。

条件で要素を取り出す方法

今回できること

この記事を読むと以下のことができるようになります。

  • 「20歳以上のひとだけを抜き出す」などの条件による標本抽出
  • 「20歳以上」かつ「身長が160cm」などの複合条件による標本抽出

これでだいぶデータ解析ができるようになります。

前回までのおさらい

前回は、Pandasの基本操作を学びました。

指定した行や列を抽出する方法を解説しています。今後、この操作が基本になるので忘れてしまったら、何度も見返してください。

前回の記事
icon
Pandasで指定した要素を取り出す方法【Dr. Python#5】

Pandasの基本操作。インデックスや行列名からデータフレームの要素を取り出す方法をまとめました。

単独の条件による抽出

まずは条件が1つだけの場合から見ていきます。

最初に全体像の確認

はじめに全体像を示すので、あとからステップごとに確認していきましょう。

今回使用するデータ

前回と変わらずGoogle Colab内のデータを使います。

import pandas as pd
df = pd.read_csv('sample_data/california_housing_train.csv')

単独条件による抽出

# 列名による抜き出し(前回の範囲)
lat =  df['latitude']

# 条件式
# テキトーな値で試します。
filt = lat > 34.0

# フィルタによる抽出
df[filt]

結果は以下のとおりです。

行インデックスを見てください。飛び飛びの値になっていますね。

つまりこれは「latitudeが34より大きい」という条件に合致したものだけを取得したことを意味します。

フィルタの部分に注目

ではステップごとに確認していきましょう。

# 列名による抜き出し(前回の範囲)
lat =  df['latitude']

# 条件式
# テキトーな値で試します。
filt = lat > 34.0

列名による抽出までは問題ありませんね? これがわからなかったら前回の記事を参考にしてください。

ではlat > 34.0を見てみましょう。

34より大きいものはTrue、小さいものはFalseになっています。欠損値の確認のときに使ったisna()の結果と似ていますね。

これを真偽値といいます。dtype: boolと書いてあるのは、「このデータのタイプ(種類)は真偽値 booleanだよ」という意味です。

この真偽値が17万件並んだデータをfiltという変数名で代入したわけです(変数名は好きに付けて構いません)。

なぜ代入したのか

lat > 34.0の結果をfiltに代入しましたが、なぜでしょう?

それは結果を保存しておきたいからです。「あとから使おう」と思っているから変数として保存しています。

したがって「今ちょっと結果だけ知りたい」という場合は変数に代入する必要はありません。

フィルタを適応させる

では真偽値からなるフィルタをもとのデータフレームに適応させます。

# フィルタによる抽出
df[filt]

こうすることによって、データフレーム全体のうちでfiltTrueの行だけが抽出されます。

一見複雑に見えたコードもステップごとに読むと内容を理解できますよね。

もっと短く書く方法

さて、上記を踏まえてもっとコードを短く書く方法を示します。

先に示した例では、latfiltという変数を作りました。

でもこれって、今後使いますか?

実はプログラムを買う上で、1回しか使わないような変数は定義しない方がいいんです。使わなくてもパソコンが覚えていますからね。無駄にメモリを消費することになります。

そのため、余計な変数を省いて書き直してみます。

df[df['latitude']>34.0]

はい。これだけです。短くなりましたね。

わからないかもしれませんが、よく見てください。

df[filt]filtはもともとlat > 34.0でしたよね。だからdf[lat>34.0]と書き直すことができます。

そしてlatdf['latitude']でした。したがって、df[df['latitude']>34.0]になるわけです。

ステップごと理解すれば簡単ですね。

複数の条件による抽出

次は条件を2つ以上にしてみます。

全体像の確認

# 1つ目の条件
condition_1 = df['latitude'] > 34.0
# 2つ目の条件
condition_2 = df['housing_median_age'] > 30.0

# 条件の適用
df[condition_1 & condition_2]

もうコードを読めるようになってきたのではないですか?

複数の条件を適用するには、条件同士を&でつなぐだけだったのですね。

短く書く際の注意

以下のように書けば、短く書けると思いますよね?

df[df['latitude'] > 34.0 & df['housing_median_age'] > 30.0]

これだとエラーが出ます

いえ、考え方は合っています。ただ、「パソコンにとって読めない」書き方になっているだけです。

ちょっと修正しましょう。

df[(df['latitude'] > 34.0) & (df['housing_median_age'] > 30.0)]

これでOKです。違いが分かりますか?

それぞれの条件を()で囲んだだけです。こうするだけで、パソコンがどこまでが条件式なのか理解できるようなりました。

論理演算とは

このような条件に当てはまるものを抽出することを論理演算といいます。

言い換えると集合を決定する計算です。

論理演算では、何が何に含まれているのか、どのような包含関係なのか、独立か、排反かなどを計算します。

&は、論理演算に使われる演算子(演算に使う記号)です。積集合を求める計算ですね。

同じように和集合を求めることもできます。和集合の記号は|です。

df[(df['latitude'] > 34.0) | (df['housing_median_age'] > 30.0)]

こうすると、「latitudeが34.0より大きいもの」あるいは「housing_median_ageが30.0より大きいもの」のいずれかを抜き出します。

つまりどちらか一方の条件が成り立てば取り出すということです。

積集合では、両方が成り立つものを抜き出します。

応用編

条件に合致した標本数を確認する

せっかくなので、実務に即した操作もやってみましょう。

(df['latitude']>34.0).sum()

# ステップごとに書き換えるとこんな感じ
bool_tmp = df['latitude']>34.0
bool_tmp.sum()

これでOKです。

df['latitude]>34.0の返り値は真偽値のリストでしたね。.sum()ではTrueを1、Falseを0とみなすので、合計値とTrueの数が一致します。

しかし、以下のようにすると別の合計値が出てきてしまいます。

df[df['latitude']>34.0].sum()

これだと抽出したデータフレームの要素の値が合計されてしまいます。

個数を数えたいのですから、これではいけませんね。

抽出した標本を保存する

さて、いろいろ手を加えたデータフレームをファイルとして保存したくなるかもしれません。

今は変数として保存されているだけでGoogle Colabとの接続が切れれば、データは失われます。

# CSVファイルとして保存したい場合
df.to_csv('/content/drive/My Drive/xxxx.csv')

# Excelファイルとして保存したい場合
df.to_excel('/content/drive/My Drive/xxxx.xlsx')

はい。これでGoogle Driveに保存しておきましょう。


historoid

おつかれさまでした。今回はここまでです。

どうでしょうか。これまででだいぶPandasの操作に慣れてきたのではありませんか?

次回は、平均値、標準偏差などの統計量を見ていきましょう。

-Pandas, プログラミング

© 2021 historoidのノート