いろいろ倉庫

KNIME、EXCEL、R、Pythonなどの備忘録

【Python】DataFrameから条件に合うデータを抜き出したりしたい

・お題:DataFrameを入手した。ここから、気になるデータを抽出したりしたい。

 

・PandasのDataFrameで特定のデータを抽出したりできるとうれしい。

・データセットを作成する。

import pandas as pd
import numpy as np
import random

df=pd.DataFrame({"Age":[random.randint(20, 60) for n in range(100)],
                "Weight":[random.randint(45, 100) for n in range(100)],
                "Income":[random.randint(200, 1000) for n in range(100)],
                "Sex":[random.choice(["f","m"]) for n in range(100)],
                "From":[random.choice(["Tokyo","Osaka","Yokohama","Nagoya","Kobe"]) for n in range(100)]})

・これで、以下のdfができる。

・次に、適当に欠損させる。

df2=df.copy()
mask=np.random.choice([0,1],p=[0.1,0.9],size=df2.shape[0]*df2.shape[1]).reshape(df2.shape[0],df2.shape[1]).astype(bool)
df2=df2.where(mask, np.nan)
df2.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100 entries, 0 to 99
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Age     84 non-null     float64
 1   Weight  92 non-null     float64
 2   Income  88 non-null     float64
 3   Sex     95 non-null     object 
 4   From    89 non-null     object 
dtypes: float64(3), object(2)
memory usage: 4.0+ KB

が返ってくる。各列10%程度欠損している。

・特定の条件に合うデータを抽出するには、queryを使う。例えば、df2から、Incomeが500以上のデータをとってくる。

df2.query("Income > 500")

ちなみに、Incomeが500~800のデータをとってくるには、query("500 < Income < 800")にすれば良い。

・Sexでfをとって来る場合、クオートに気を付ける。文字列fと一緒か否かを判別するので、==を使う。また、意味の塊ごとにクオートの数を揃える。

df2.query("Sex == 'f'")

ちなみに、df2.query('Sex == "f"')でも良い。否定は、!=にする。

・特定の列で複数の条件にあてはまるデータを取得するには、リストにすれば良い。

df2.query("From == ['Tokyo','Nagoya']")

・複数の列の条件でアンド検索することもできる。Sex == mかつWeight > 80なら以下のような感じ。

df2.query("Sex == 'm' & Weight > 80")

ちなみに、オア検索は|でいける。df2.query("Sex == 'm' | Weight > 80")

・queryを使わない方法として、True/Falseの列を作成してから、行をとって来る方法もある。

df2["Sex"]=="m"

df2[df2["Sex"]=="m"]

・これを利用して、Fromにyが含まれるデータを抽出できる。

df2[df2["From"].str.contains("y", na=False)]

str.containsはデフォルトでNaNが残ってしまうので、NaNをどう処理するか、指定しておく。

・NaNのデータを除くこともできる。

df2[df2["Age"].notna()]

ちなみに、notna()をisna()にすればNaNのものだけ釣ってくることができる。

・せっかくなので昇順に並べ替えたい。sort_valuesでいける。

df2.sort_values("Age")

ちなみに、引数ascendingにFalseを与えると、降順になる。

 

・いろいろ使えそう。

 

おわり。