🚀 ステップ25: データを抽出しよう(応用編)
より便利で強力なデータ抽出テクニックを学ぼう!
ステップ24では、条件抽出の基本を学びました。今回は、より便利で効率的な抽出方法を学びます。query()、isin()、between()などを使うと、複雑な条件もシンプルに書くことができます。
📖 このステップで学ぶこと
・query()メソッド – SQLライクな抽出
・isin()メソッド – リストに含まれるか判定
・between()メソッド – 範囲指定
・文字列の高度な検索
・複数の抽出方法の組み合わせ
学習時間の目安: 2.5〜3時間
🎯 1. query() – SQLライクな抽出
ステップ24で学んだ条件抽出は、カッコが多くて読みにくくなることがあります。query()を使うと、文字列で条件を書けるのでコードがシンプルになります。
🔰 query()とは?
query()は、SQLのWHERE句のような書き方で条件を指定できるメソッドです。データベースを扱ったことがある方には馴染みやすい書き方です。
📝 query()の書き方
df.query(‘条件式’)
・条件式は文字列(シングルクォートまたはダブルクォート)で囲みます
・列名はそのまま書きます(クォート不要)
・andやorが使えます(&や|の代わり)
・変数を使う時は@をつけます
📝 通常の方法との比較
まず、通常の条件抽出とquery()の違いを見てみましょう。
コード:通常の方法 vs query()
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'年齢': [25, 23, 27, 24, 26],
'年収': [400, 380, 450, 390, 420]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 通常の方法(年齢25歳以上)
print("通常の方法(年齢25歳以上):")
print(df[df['年齢'] >= 25])
print()
# query()を使う方法(年齢25歳以上)
print("query()を使う方法(年齢25歳以上):")
print(df.query('年齢 >= 25'))
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 名前 年齢 年収 0 太郎 25 400 1 花子 23 380 2 次郎 27 450 3 美咲 24 390 4 健太 26 420 通常の方法(年齢25歳以上): 名前 年齢 年収 0 太郎 25 400 2 次郎 27 450 4 健太 26 420 query()を使う方法(年齢25歳以上): 名前 年齢 年収 0 太郎 25 400 2 次郎 27 450 4 健太 26 420
💡 コードの解説
通常の方法:df[df[‘年齢’] >= 25]
・dfが2回出てくる
・列名をクォートで囲む必要がある
・カッコが多くなりがち
query()の方法:df.query(‘年齢 >= 25’)
・dfは1回だけ
・列名はそのまま書ける
・シンプルで読みやすい
📌 query()の利点
| 比較項目 | 通常の方法 | query() |
| 書き方 | df[df[‘列名’] >= 値] | df.query(‘列名 >= 値’) |
| AND条件 | (条件1) & (条件2) | 条件1 and 条件2 |
| OR条件 | (条件1) | (条件2) | 条件1 or 条件2 |
| 読みやすさ | カッコが多くなりがち | シンプルで直感的 |
📝 query()で複数条件
query()では、andとorをそのまま使えます。カッコで囲む必要もありません。
コード:query()で複数条件
import pandas as pd
data = {
'商品名': ['商品A', '商品B', '商品C', '商品D', '商品E'],
'価格': [1000, 1500, 2000, 800, 1200],
'在庫': [50, 80, 30, 90, 60]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 価格1000円以上 かつ 在庫50個以上
print("価格1000円以上 かつ 在庫50個以上:")
print(df.query('価格 >= 1000 and 在庫 >= 50'))
print()
# 価格1500円以下 または 在庫70個以上
print("価格1500円以下 または 在庫70個以上:")
print(df.query('価格 <= 1500 or 在庫 >= 70'))
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 商品名 価格 在庫 0 商品A 1000 50 1 商品B 1500 80 2 商品C 2000 30 3 商品D 800 90 4 商品E 1200 60 価格1000円以上 かつ 在庫50個以上: 商品名 価格 在庫 0 商品A 1000 50 1 商品B 1500 80 4 商品E 1200 60 価格1500円以下 または 在庫70個以上: 商品名 価格 在庫 0 商品A 1000 50 1 商品B 1500 80 3 商品D 800 90 4 商品E 1200 60
💡 query()での論理演算子
query()では以下の演算子が使えます:
and → 「かつ」(通常の方法では&)
or → 「または」(通常の方法では|)
not → 「〜ではない」(通常の方法では~)
通常のPythonのキーワードがそのまま使えるので、直感的です!
📘 query()で変数を使う
条件の値を変数で指定したい場合は、変数名の前に@をつけます。
コード:query()で変数を使う
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'年齢': [25, 23, 27, 24, 26],
'年収': [400, 380, 450, 390, 420]
}
df = pd.DataFrame(data)
# 変数を定義
min_age = 25
min_salary = 400
# @をつけて変数を参照
print(f"年齢{min_age}歳以上 かつ 年収{min_salary}万円以上:")
result = df.query('年齢 >= @min_age and 年収 >= @min_salary')
print(result)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
年齢25歳以上 かつ 年収400万円以上: 名前 年齢 年収 0 太郎 25 400 2 次郎 27 450 4 健太 26 420
💡 @(アットマーク)の意味
@変数名と書くと、query()の外で定義した変数を参照できます。
これが便利な場面:
・ユーザーが入力した値で抽出したい時
・ループで異なる条件を試したい時
・条件を動的に変えたい時
📋 2. isin() – リストに含まれるか判定
isin()は、指定したリストのいずれかに該当するデータを抽出します。「東京または大阪または福岡」のような条件を書く時、ORを何度も書かなくて済みます。
🔰 isin()とは?
isin()は「〜の中に含まれるか」を判定するメソッドです。SQLの「IN」句に相当します。
📝 isin()の書き方
df[df[‘列名’].isin([値1, 値2, 値3])]
・リスト([ ])の中に、含めたい値を列挙します
・リストのいずれかに該当すればTrueになります
・文字列でも数値でも使えます
コード:isin()の基本
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太', '桜子'],
'都市': ['東京', '大阪', '名古屋', '福岡', '東京', '札幌']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 東京、大阪、福岡のいずれかに住んでいる人
cities = ['東京', '大阪', '福岡']
print(f"{cities}のいずれかに住んでいる人:")
print(df[df['都市'].isin(cities)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 名前 都市 0 太郎 東京 1 花子 大阪 2 次郎 名古屋 3 美咲 福岡 4 健太 東京 5 桜子 札幌 ['東京', '大阪', '福岡']のいずれかに住んでいる人: 名前 都市 0 太郎 東京 1 花子 大阪 3 美咲 福岡 4 健太 東京
💡 isin()の利点
通常のOR条件と比較してみましょう:
OR条件を使った場合(長い!):
df[(df['都市'] == '東京') | (df['都市'] == '大阪') | (df['都市'] == '福岡')]
isin()を使った場合(シンプル!):
df[df['都市'].isin(['東京', '大阪', '福岡'])]
対象が多いほど、isin()の方がシンプルになります!
📝 数値でもisin()を使える
コード:数値でisin()を使う
import pandas as pd
data = {
'商品コード': [101, 102, 103, 104, 105, 106],
'商品名': ['商品A', '商品B', '商品C', '商品D', '商品E', '商品F'],
'価格': [1000, 1500, 2000, 1200, 1800, 900]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 特定の商品コード(101, 103, 105)のみ
target_codes = [101, 103, 105]
print(f"商品コード{target_codes}のデータ:")
print(df[df['商品コード'].isin(target_codes)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 商品コード 商品名 価格 0 101 商品A 1000 1 102 商品B 1500 2 103 商品C 2000 3 104 商品D 1200 4 105 商品E 1800 5 106 商品F 900 商品コード[101, 103, 105]のデータ: 商品コード 商品名 価格 0 101 商品A 1000 2 103 商品C 2000 4 105 商品E 1800
📘 isin()の否定(NOT IN)
「〜に含まれない」を判定するには、~(チルダ)を使って否定します。
コード:isin()の否定
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'部署': ['営業', '開発', '営業', '総務', '開発']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 営業と開発「以外」の部署
exclude_depts = ['営業', '開発']
print(f"{exclude_depts}以外の部署:")
print(df[~df['部署'].isin(exclude_depts)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 名前 部署 0 太郎 営業 1 花子 開発 2 次郎 営業 3 美咲 総務 4 健太 開発 ['営業', '開発']以外の部署: 名前 部署 3 美咲 総務
💡 ~(チルダ)の意味
~は「否定」を表す演算子です。
・df[df['列'].isin([値])] → 含まれる行を抽出
・df[~df['列'].isin([値])] → 含まれない行を抽出
チルダはキーボードでShift + ^(ハット)で入力できます。
📊 3. between() – 範囲指定
between()は、〜から〜までという範囲を簡単に指定できます。「100以上200以下」のような範囲条件をシンプルに書けます。
🔰 between()とは?
📝 between()の書き方
df[df[‘列名’].between(最小値, 最大値)]
・最小値と最大値の両方を含みます(以上・以下)
・数値だけでなく、日付にも使えます
コード:between()の基本
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太', '桜子'],
'年齢': [25, 23, 27, 24, 26, 22]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 24歳から26歳まで
print("24歳から26歳まで:")
print(df[df['年齢'].between(24, 26)])
print()
# 通常の方法と比較
print("通常の方法(同じ結果):")
print(df[(df['年齢'] >= 24) & (df['年齢'] <= 26)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 名前 年齢 0 太郎 25 1 花子 23 2 次郎 27 3 美咲 24 4 健太 26 5 桜子 22 24歳から26歳まで: 名前 年齢 0 太郎 25 3 美咲 24 4 健太 26 通常の方法(同じ結果): 名前 年齢 0 太郎 25 3 美咲 24 4 健太 26
💡 between()の利点
通常の方法:df[(df['年齢'] >= 24) & (df['年齢'] <= 26)]
・カッコが多い
・列名を2回書く必要がある
between():df[df['年齢'].between(24, 26)]
・シンプルで読みやすい
・「24から26まで」と直感的
📝 範囲外を取得
「範囲内」ではなく「範囲外」のデータを取得するには、~(チルダ)で否定します。
コード:between()の否定
import pandas as pd
data = {
'商品名': ['商品A', '商品B', '商品C', '商品D', '商品E'],
'価格': [800, 1500, 2500, 1000, 1200]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 1000円から2000円の範囲内
print("1000円〜2000円:")
print(df[df['価格'].between(1000, 2000)])
print()
# 1000円から2000円の範囲外(~で否定)
print("1000円〜2000円の範囲外:")
print(df[~df['価格'].between(1000, 2000)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame: 商品名 価格 0 商品A 800 1 商品B 1500 2 商品C 2500 3 商品D 1000 4 商品E 1200 1000円〜2000円: 商品名 価格 1 商品B 1500 3 商品D 1000 4 商品E 1200 1000円〜2000円の範囲外: 商品名 価格 0 商品A 800 2 商品C 2500
📘 日付の範囲指定
between()は日付データにも使えます。特定の期間のデータを抽出するのに便利です。
コード:日付の範囲指定
import pandas as pd
data = {
'日付': ['2024-01-05', '2024-01-15', '2024-01-25', '2024-02-05', '2024-02-15'],
'売上': [120, 135, 150, 145, 160]
}
df = pd.DataFrame(data)
# 日付列を日付型に変換
df['日付'] = pd.to_datetime(df['日付'])
print("DataFrame:")
print(df)
print()
# 1月10日から1月末まで
start_date = '2024-01-10'
end_date = '2024-01-31'
print(f"{start_date}から{end_date}まで:")
result = df[df['日付'].between(start_date, end_date)]
print(result)
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame:
日付 売上
0 2024-01-05 120
1 2024-01-15 135
2 2024-01-25 150
3 2024-02-05 145
4 2024-02-15 160
2024-01-10から2024-01-31まで:
日付 売上
1 2024-01-15 135
2 2024-01-25 150
💡 日付型への変換
pd.to_datetime(df['日付'])
・文字列の日付を、Pandasの日付型に変換します
・日付型にすると、日付の比較や範囲指定が正確にできます
・「2024-01-15」のような形式を自動的に認識します
🔤 4. 文字列の高度な検索
ステップ24で学んだstr.contains()に加えて、より高度な文字列検索テクニックを学びます。
🔰 複数パターンのいずれかを含む
「リンゴまたはオレンジを含む」のように、複数のパターンを|(パイプ)で区切って検索できます。
コード:複数パターンの検索
import pandas as pd
data = {
'商品名': ['リンゴジュース', 'バナナ', 'オレンジジュース',
'リンゴ', 'グレープジュース', 'オレンジ']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 「リンゴ」または「オレンジ」を含む
print("「リンゴ」または「オレンジ」を含む:")
pattern = 'リンゴ|オレンジ'
print(df[df['商品名'].str.contains(pattern)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame:
商品名
0 リンゴジュース
1 バナナ
2 オレンジジュース
3 リンゴ
4 グレープジュース
5 オレンジ
「リンゴ」または「オレンジ」を含む:
商品名
0 リンゴジュース
2 オレンジジュース
3 リンゴ
5 オレンジ
💡 パターンの書き方
'リンゴ|オレンジ'
・|(パイプ)で複数のパターンを区切ります
・「リンゴ」または「オレンジ」のいずれかを含む行を抽出
・これは正規表現の書き方です
3つ以上のパターンも可能:'リンゴ|オレンジ|バナナ'
📝 文字列の長さで抽出
str.len()を使うと、文字列の長さで抽出できます。
コード:文字列の長さで抽出
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎太', '美咲', '健太郎']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# 2文字の名前
print("2文字の名前:")
print(df[df['名前'].str.len() == 2])
print()
# 3文字以上の名前
print("3文字以上の名前:")
print(df[df['名前'].str.len() >= 3])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame:
名前
0 太郎
1 花子
2 次郎太
3 美咲
4 健太郎
2文字の名前:
名前
0 太郎
1 花子
3 美咲
3文字以上の名前:
名前
2 次郎太
4 健太郎
📘 大文字小文字を区別しない検索
英語のデータを検索する時、大文字小文字を区別せずに検索したい場合があります。case=Falseオプションを使います。
コード:大文字小文字を区別しない検索
import pandas as pd
data = {
'メールアドレス': ['taro@example.com', 'HANAKO@EXAMPLE.COM',
'jiro@Example.Com', 'misaki@test.com']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print()
# example.comを含む(大文字小文字を区別しない)
print("example.comを含む(大文字小文字区別なし):")
print(df[df['メールアドレス'].str.contains('example.com', case=False)])
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
DataFrame:
メールアドレス
0 taro@example.com
1 HANAKO@EXAMPLE.COM
2 jiro@Example.Com
3 misaki@test.com
example.comを含む(大文字小文字区別なし):
メールアドレス
0 taro@example.com
1 HANAKO@EXAMPLE.COM
2 jiro@Example.Com
📌 文字列検索メソッドのまとめ
| メソッド | 説明 | 使用例 |
| str.contains() | 含む | str.contains('検索語') |
| str.startswith() | 〜で始まる | str.startswith('A') |
| str.endswith() | 〜で終わる | str.endswith('1') |
| str.len() | 文字数を取得 | str.len() == 3 |
🔗 5. 複数の抽出方法を組み合わせる
ここまで学んだ抽出方法を組み合わせて、実際のデータ分析で使うような複雑な条件を表現してみましょう。
コード:売上データの詳細分析
import pandas as pd
# 売上データを作成
data = {
'日付': ['2024-01-10', '2024-01-15', '2024-01-20', '2024-01-25',
'2024-02-05', '2024-02-10', '2024-02-15'],
'店舗': ['新宿店', '渋谷店', '新宿店', '池袋店', '新宿店', '渋谷店', '池袋店'],
'商品': ['リンゴジュース', 'バナナ', 'オレンジジュース', 'リンゴ',
'リンゴジュース', 'グレープジュース', 'バナナ'],
'売上': [15000, 8000, 18000, 12000, 16000, 20000, 9000]
}
df = pd.DataFrame(data)
print("全データ:")
print(df)
print()
# 条件1: 新宿店または渋谷店
print("条件1: 新宿店または渋谷店")
store_filter = df['店舗'].isin(['新宿店', '渋谷店'])
print(df[store_filter])
print()
# 条件2: 売上が10000円以上20000円以下
print("条件2: 売上10000円〜20000円")
sales_filter = df['売上'].between(10000, 20000)
print(df[sales_filter])
print()
# 条件3: 商品名に「ジュース」を含む
print("条件3: 商品名に「ジュース」を含む")
product_filter = df['商品'].str.contains('ジュース')
print(df[product_filter])
print()
# 全ての条件を組み合わせ
print("全ての条件を満たす:")
combined = df[store_filter & sales_filter & product_filter]
print(combined)
print(f"\n該当件数: {len(combined)}件")
print(f"合計売上: {combined['売上'].sum():,}円")
※ 画面が小さい場合は、コードブロックを横にスクロールできます
実行結果
全データ:
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
1 2024-01-15 渋谷店 バナナ 8000
2 2024-01-20 新宿店 オレンジジュース 18000
3 2024-01-25 池袋店 リンゴ 12000
4 2024-02-05 新宿店 リンゴジュース 16000
5 2024-02-10 渋谷店 グレープジュース 20000
6 2024-02-15 池袋店 バナナ 9000
条件1: 新宿店または渋谷店
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
1 2024-01-15 渋谷店 バナナ 8000
2 2024-01-20 新宿店 オレンジジュース 18000
4 2024-02-05 新宿店 リンゴジュース 16000
5 2024-02-10 渋谷店 グレープジュース 20000
条件2: 売上10000円〜20000円
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
2 2024-01-20 新宿店 オレンジジュース 18000
3 2024-01-25 池袋店 リンゴ 12000
4 2024-02-05 新宿店 リンゴジュース 16000
5 2024-02-10 渋谷店 グレープジュース 20000
条件3: 商品名に「ジュース」を含む
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
2 2024-01-20 新宿店 オレンジジュース 18000
4 2024-02-05 新宿店 リンゴジュース 16000
5 2024-02-10 渋谷店 グレープジュース 20000
全ての条件を満たす:
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
2 2024-01-20 新宿店 オレンジジュース 18000
4 2024-02-05 新宿店 リンゴジュース 16000
5 2024-02-10 渋谷店 グレープジュース 20000
該当件数: 4件
合計売上: 69,000円
💡 条件を変数に分ける利点
各条件を変数に格納しておくと:
・コードが読みやすくなる
・条件ごとに結果を確認できる
・条件の組み合わせを変えやすい
複雑な分析をする時は、この方法がおすすめです!
📝 練習問題
ここまで学んだことを、実際に手を動かして確認しましょう。
問題1:query()の基本(初級)
📋 問題
以下のDataFrameから、年齢が24歳以上のデータをquery()を使って抽出してください。
・名前: ['太郎', '花子', '次郎', '美咲', '健太']
・年齢: [25, 23, 27, 24, 26]
解答例を見る
コード
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太'],
'年齢': [25, 23, 27, 24, 26]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print("\n年齢24歳以上:")
result = df.query('年齢 >= 24')
print(result)
実行結果
DataFrame: 名前 年齢 0 太郎 25 1 花子 23 2 次郎 27 3 美咲 24 4 健太 26 年齢24歳以上: 名前 年齢 0 太郎 25 2 次郎 27 3 美咲 24 4 健太 26
問題2:isin()の活用(初級)
📋 問題
以下のDataFrameから、都市が「東京」「大阪」「名古屋」のいずれかのデータを抽出してください。
・名前: ['太郎', '花子', '次郎', '美咲', '健太', '桜子']
・都市: ['東京', '福岡', '大阪', '札幌', '名古屋', '東京']
解答例を見る
コード
import pandas as pd
data = {
'名前': ['太郎', '花子', '次郎', '美咲', '健太', '桜子'],
'都市': ['東京', '福岡', '大阪', '札幌', '名古屋', '東京']
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
cities = ['東京', '大阪', '名古屋']
print(f"\n{cities}のいずれか:")
result = df[df['都市'].isin(cities)]
print(result)
print(f"\n該当者数: {len(result)}人")
実行結果
DataFrame: 名前 都市 0 太郎 東京 1 花子 福岡 2 次郎 大阪 3 美咲 札幌 4 健太 名古屋 5 桜子 東京 ['東京', '大阪', '名古屋']のいずれか: 名前 都市 0 太郎 東京 2 次郎 大阪 4 健太 名古屋 5 桜子 東京 該当者数: 4人
問題3:between()で範囲指定(中級)
📋 問題
以下のDataFrameから、価格が1000円以上2000円以下の商品を抽出してください。
・商品名: ['商品A', '商品B', '商品C', '商品D', '商品E']
・価格: [800, 1500, 2500, 1000, 1200]
解答例を見る
コード
import pandas as pd
data = {
'商品名': ['商品A', '商品B', '商品C', '商品D', '商品E'],
'価格': [800, 1500, 2500, 1000, 1200]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print("\n1000円〜2000円:")
result = df[df['価格'].between(1000, 2000)]
print(result)
print(f"\n該当商品数: {len(result)}個")
print(f"平均価格: {result['価格'].mean():.0f}円")
実行結果
DataFrame: 商品名 価格 0 商品A 800 1 商品B 1500 2 商品C 2500 3 商品D 1000 4 商品E 1200 1000円〜2000円: 商品名 価格 1 商品B 1500 3 商品D 1000 4 商品E 1200 該当商品数: 3個 平均価格: 1233円
問題4:文字列検索(中級)
📋 問題
以下のDataFrameから、商品名に「ジュース」を含む商品を抽出してください。
・商品名: ['リンゴジュース', 'バナナ', 'オレンジジュース', 'リンゴ', 'グレープジュース']
・価格: [150, 100, 180, 120, 160]
解答例を見る
コード
import pandas as pd
data = {
'商品名': ['リンゴジュース', 'バナナ', 'オレンジジュース', 'リンゴ', 'グレープジュース'],
'価格': [150, 100, 180, 120, 160]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
print("\n商品名に「ジュース」を含む:")
result = df[df['商品名'].str.contains('ジュース')]
print(result)
print(f"\nジュースの種類: {len(result)}種類")
print(f"平均価格: {result['価格'].mean():.0f}円")
実行結果
DataFrame:
商品名 価格
0 リンゴジュース 150
1 バナナ 100
2 オレンジジュース 180
3 リンゴ 120
4 グレープジュース 160
商品名に「ジュース」を含む:
商品名 価格
0 リンゴジュース 150
2 オレンジジュース 180
4 グレープジュース 160
ジュースの種類: 3種類
平均価格: 163円
問題5:query()とisin()の組み合わせ(上級)
📋 問題
以下のDataFrameから、部署が「営業」または「開発」で、かつ年収が400万円以上のデータを抽出してください。
・名前: ['佐藤', '鈴木', '田中', '高橋', '伊藤', '渡辺']
・部署: ['営業', '開発', '営業', '総務', '開発', '営業']
・年収: [450, 520, 380, 490, 580, 420]
解答例を見る
コード
import pandas as pd
data = {
'名前': ['佐藤', '鈴木', '田中', '高橋', '伊藤', '渡辺'],
'部署': ['営業', '開発', '営業', '総務', '開発', '営業'],
'年収': [450, 520, 380, 490, 580, 420]
}
df = pd.DataFrame(data)
print("DataFrame:")
print(df)
# 方法1: isin()と通常の条件を組み合わせ
target_depts = ['営業', '開発']
print(f"\n{target_depts} かつ 年収400万円以上:")
result = df[df['部署'].isin(target_depts) & (df['年収'] >= 400)]
print(result)
print(f"\n該当者数: {len(result)}人")
print(f"平均年収: {result['年収'].mean():.0f}万円")
実行結果
DataFrame: 名前 部署 年収 0 佐藤 営業 450 1 鈴木 開発 520 2 田中 営業 380 3 高橋 総務 490 4 伊藤 開発 580 5 渡辺 営業 420 ['営業', '開発'] かつ 年収400万円以上: 名前 部署 年収 0 佐藤 営業 450 1 鈴木 開発 520 4 伊藤 開発 580 5 渡辺 営業 420 該当者数: 4人 平均年収: 493万円
問題6:複数メソッドの組み合わせ(上級)
📋 問題
以下のDataFrameから、以下の条件を全て満たすデータを抽出してください:
1. 店舗が「新宿店」「渋谷店」のいずれか
2. 売上が10000円以上30000円以下
3. 商品名に「リンゴ」または「オレンジ」を含む
・日付: ['2024-01-10', '2024-01-15', '2024-01-20', '2024-01-25', '2024-02-05']
・店舗: ['新宿店', '渋谷店', '新宿店', '池袋店', '新宿店']
・商品: ['リンゴジュース', 'バナナ', 'オレンジジュース', 'リンゴ', 'グレープジュース']
・売上: [15000, 8000, 25000, 12000, 35000]
解答例を見る
コード
import pandas as pd
data = {
'日付': ['2024-01-10', '2024-01-15', '2024-01-20', '2024-01-25', '2024-02-05'],
'店舗': ['新宿店', '渋谷店', '新宿店', '池袋店', '新宿店'],
'商品': ['リンゴジュース', 'バナナ', 'オレンジジュース', 'リンゴ', 'グレープジュース'],
'売上': [15000, 8000, 25000, 12000, 35000]
}
df = pd.DataFrame(data)
print("全データ:")
print(df)
# 条件1: 店舗が新宿店または渋谷店
cond1 = df['店舗'].isin(['新宿店', '渋谷店'])
# 条件2: 売上が10000円〜30000円
cond2 = df['売上'].between(10000, 30000)
# 条件3: 商品名にリンゴまたはオレンジを含む
cond3 = df['商品'].str.contains('リンゴ|オレンジ')
# 全ての条件を満たす
result = df[cond1 & cond2 & cond3]
print("\n全ての条件を満たすデータ:")
print(result)
print(f"\n該当件数: {len(result)}件")
if len(result) > 0:
print(f"合計売上: {result['売上'].sum():,}円")
実行結果
全データ:
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
1 2024-01-15 渋谷店 バナナ 8000
2 2024-01-20 新宿店 オレンジジュース 25000
3 2024-01-25 池袋店 リンゴ 12000
4 2024-02-05 新宿店 グレープジュース 35000
全ての条件を満たすデータ:
日付 店舗 商品 売上
0 2024-01-10 新宿店 リンゴジュース 15000
2 2024-01-20 新宿店 オレンジジュース 25000
該当件数: 2件
合計売上: 40,000円
🎯 このステップのまとめ
✅ 学んだこと
✓ query()で文字列形式で条件を書ける(andやorが使える)
✓ isin()で複数の値のいずれかに該当するか判定できる
✓ between()で範囲を簡単に指定できる
✓ str.contains()で文字列の部分一致検索ができる
✓ str.startswith()/endswith()で前方・後方一致検索ができる
✓ 複数のメソッドを組み合わせて複雑な条件を表現できる
💡 次のステップに進む前に確認
以下のことができるようになったか確認しましょう:
□ query()を使えますか?
□ isin()で複数値の判定ができますか?
□ between()で範囲指定ができますか?
□ 文字列検索の各メソッドを使い分けられますか?
これらができたら、次のステップに進みましょう!
❓ よくある質問
Q1: query()と通常の方法はどう使い分けますか?
A: 短い条件ならquery()が読みやすく、複雑な条件や変数を多用する場合は通常の方法が良いです。好みや状況に応じて選んでください。両方使えるようになっておくと便利です。
Q2: isin()でNoneやNaNも判定できますか?
A: isin()は通常の値の判定に使います。欠損値(NaN)を判定したい場合はisnull()またはnotnull()を使ってください。df[df['列'].isnull()]のように書きます。
Q3: between()は両端を含みますか?
A: はい、両端を含みます(以上・以下)。between(10, 20)は10以上20以下です。片方だけ含めたい場合は、通常の比較演算子(>=, <)を使いましょう。
Q4: str.contains()でエラーが出ます
A: 列にNaN(欠損値)が含まれている可能性があります。na=Falseオプションを追加してください。df['列'].str.contains('検索語', na=False)これでNaNを無視できます。
Q5: 正規表現は使えますか?
A: はい、str.contains()はデフォルトで正規表現が有効です。'リンゴ|オレンジ'のような書き方ができます。正規表現を使わない場合はregex=Falseオプションを指定してください。
学習メモ
Pythonデータ分析入門 - Step 25