PythonのPandasでデータを抽出しよう

PythonのPandasでデータを抽出しよう

データ分析の第一歩は、必要なデータを効率的に抽出することから始まります。

PythonのPandasライブラリは、データのフィルタリングや特定の列の選択を簡単に行うための強力なツールです。

今回は、Pandasを使用してデータを抽出する基本的な方法を解説します。

Pandasの基礎知識

 Pandasとは?

PandasはPythonのデータ分析ライブラリとして、構造化データの操作に優れています。

特に表形式のデータ(データフレーム)を効率的に操作するための豊富な機能があります。

これにより、データの処理や分析が迅速かつ効果的に行えます。ただ、慣れが必要です。

 

 Pandasの基本データ構造(SeriesとDataFrame)

Pandasには二つの主要なデータ構造があります。SeriesDataFrameです。

  • Series: 一次元の配列で、インデックス付きのデータ
  • DataFrame: 二次元のデータ構造で、行と列を持つデータの集合体

 

Seriesは一次元の配列で、インデックス付きのデータです。

主に以下の特徴があります。

  • インデックス:各データに対してラベルが付けられており、インデックスを使ってデータにアクセスできます。
  • 単一データ型:一つのSeriesは単一のデータ型(例えば整数、文字列など)のみを保持します。

 

簡単な例を見ていきます。

以下、コードです。

import pandas as pd

# シンプルなSeriesの例
data = [10, 20, 30, 40, 50]

series = pd.Series(data)

print(series)

 

以下、実行結果です。

0    10
1    20
2    30
3    40
4    50
dtype: int64

 

DataFrameは二次元のデータ構造で、行と列を持つデータの集合体です。

  • 複数の列:DataFrameは複数のSeriesを列として持ち、各列は異なるデータ型を持つことができます。
  • インデックス:行にもインデックスがあり、行・列の両方のインデックスを使ってデータにアクセスできます。

 

簡単な例を見ていきます。

以下、コードです。

import pandas as pd

# シンプルなDataFrameの例
data = {
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 32, 37],
    'salary': [50000, 60000, 75000]
}

df = pd.DataFrame(data)

print(df)

 

以下、実行結果です。

      name  age  salary
0    Alice   25   50000
1      Bob   32   60000
2  Charlie   37   75000

 

 データの読み込みと表示

以降で利用するデータセットを読み込みます。

利用するデータセットを以下からダウンロードできます。

data.csv
https://www.salesanalytics.co.jp/6e1o

 

以下のコードで、データセットを読み込みます。

import pandas as pd

# CSVファイルの読み込み
df = pd.read_csv('data.csv')

# データの表示
print(df)

 

以下、実行結果です。

      name  age  salary   department    status  column1  column2 group_column  \
0    Alice   25   50000           HR    active       12        8            A   
1      Bob   32   60000      Finance  inactive       15        5            B   
2  Charlie   37   75000  Engineering    active       10        7            A   
3    David   29   58000    Marketing  inactive       17        9            B   
4      Eva   41   62000        Sales    active       19        4            A   

   user_id  last_login  
0        1  2024-05-01  
1        2  2024-04-30  
2        3  2024-05-05  
3        4  2024-04-28  
4        5  2024-05-03

 

データのフィルタリング

 条件を使ったフィルタリングの基本

Pandasでは、データフレームの列に条件を設定しフィルタリングをすることができます。

以下、コードです。

# 条件に基づいてフィルタリング
filtered_df = df[df['column1'] > 12]

print(filtered_df)

 

以下、実行結果です。

    name  age  salary department    status  column1  column2 group_column  \
1    Bob   32   60000    Finance  inactive       15        5            B   
3  David   29   58000  Marketing  inactive       17        9            B   
4    Eva   41   62000      Sales    active       19        4            A   

   user_id  last_login  
1        2  2024-04-30  
3        4  2024-04-28  
4        5  2024-05-03

 

論理演算子を使った高度なフィルタリング

Pandasでは、複数の条件を組み合わせてデータをフィルタリングするために、論理演算子を使用することができます。

以下の論理演算子がよく使われます。

  • &(AND)
  • |(OR)
  • ~(NOT)

 

 AND条件

AND条件を使用すると、複数の条件すべてが満たされた場合にのみデータを抽出します。

以下の例では、column1の値が12より大きく、かつcolumn2の値が6未満である行をフィルタリングします。

# AND条件を使ったフィルタリング
filtered_df = df[(df['column1'] > 12) &amp; (df['column2'] < 6)]

print(filtered_df)

 

以下、実行結果です。

  name  age  salary department    status  column1  column2 group_column  \
1  Bob   32   60000    Finance  inactive       15        5            B   
4  Eva   41   62000      Sales    active       19        4            A   

   user_id  last_login  
1        2  2024-04-30  
4        5  2024-05-03

 

 OR条件

OR条件を使用すると、いずれかの条件が満たされた場合にデータを抽出します。

以下の例では、column1の値が12より大きいか、column2の値が6未満である行をフィルタリングします。

# OR条件を使ったフィルタリング
filtered_df = df[(df['column1'] > 12) | (df['column2'] < 6)]

print(filtered_df)

 

以下、実行結果です。

    name  age  salary department    status  column1  column2 group_column  \
1    Bob   32   60000    Finance  inactive       15        5            B   
3  David   29   58000  Marketing  inactive       17        9            B   
4    Eva   41   62000      Sales    active       19        4            A   

   user_id  last_login  
1        2  2024-04-30  
3        4  2024-04-28  
4        5  2024-05-03

 

 NOT条件

NOT条件を使用すると、条件を満たさないデータを抽出します。

以下の例では、column1の値が12より大きくない行をフィルタリングします。

# NOT条件を使ったフィルタリング
filtered_df = df[~(df['column1'] > 12)] 

print(filtered_df)

 

以下、実行結果です。

      name  age  salary   department  status  column1  column2 group_column  \
0    Alice   25   50000           HR  active       12        8            A   
2  Charlie   37   75000  Engineering  active       10        7            A   

   user_id  last_login  
0        1  2024-05-01  
2        3  2024-05-05

 

 メソッドチェーンを活用したフィルタリング

Pandasでは、メソッドチェーンを使って複数の操作を連続して行うことができます。

これにより、データ処理のコードがより直感的で読みやすくなります。

以下のコード例では、columnに特定のキーワードを含む行をフィルタリングし、その後、NaN値を含む行を削除しています。

import pandas as pd


# サンプルデータフレームの作成
data = {
    'column': ['keyword1', 'example', 'keyword2', None, 'sample'],
    'value': [10, 20, 30, 40, 50]
}
df1 = pd.DataFrame(data) 

# メソッドチェーンでフィルタリング
filtered_df = df1[df1['column'].str.contains('keyword', na=False)].dropna() 

print(filtered_df)

 

以下、実行結果です。

     column  value
0  keyword1     10
2  keyword2     30

 

簡単に今回のメソッドチェーンを解説します。

  • 文字列のフィルタリングdf['column'].str.contains('keyword', na=False)
    • str.contains('keyword')は、columnの各値が'keyword'を含むかどうかをチェックします。
    • na=Falseは、NaN値をFalseとして扱うことで、NaN値の行をフィルタリングの対象外にします。
  • NaN値の削除.dropna()
    • dropna()は、DataFrameからNaN値を含む行を削除します。

この方法では、複数のデータ処理ステップを一つのコードブロックで連続して実行することができます。

これにより、コードの可読性が向上し、データ処理の各ステップを明確に追跡することができます。

 

特定の列の選択

Pandasでは、データフレームから特定の列を選択する操作が簡単に行えます。

単一列、複数列の選択方法、列のリネーム並び替え特定の条件に基づく列の選択方法について解説します。

 

 単一列の選択

以下、コードです。

# 単一列の選択
selected_column = df['column1']

print(selected_column)

 

以下、実行結果です。

0    12
1    15
2    10
3    17
4    19
Name: column1, dtype: int64

 

 複数列の選択

以下、コードです。

# 複数列の選択
selected_columns = df[['column1', 'column2']]

print(selected_columns)

 

以下、実行結果です。

   column1  column2
0       12        8
1       15        5
2       10        7
3       17        9
4       19        4

 

 列のリネームと並び替え

以下、コードです。

# DataFrameのコピー
df2 = df.copy()

# 列のリネーム: group_column -> group
df2.rename(columns={'group_column': 'group'}, inplace=True)

# 列の並び替え
df2 = df2[['group', 'column1', 'column2']]

print(df2)

 

以下、実行結果です。

  group  column1  column2
0     A       12        8
1     B       15        5
2     A       10        7
3     B       17        9
4     A       19        4

 

 列名が特定の条件を満たす列を選択

以下のコードは、列名が特定の条件を満たす列を選択する方法を示しています。

# 条件に基づく列の選択
selected_columns = df.loc[:, df.columns.str.startswith('column')]
print(selected_columns)

 

以下、実行結果です。

   column1  column2
0       12        8
1       15        5
2       10        7
3       17        9
4       19        4

 

これらの方法を使うことで、データフレームから必要な列を効率的に選択し、データの操作を簡単に行うことができます。

 

インデックスとスライシング

Pandasでは、データフレームのインデックスを設定したり、スライシングを行うことで、データの特定の部分を抽出することができます。

インデックスの設定とリセット、行と列のスライシング、.loc.ilocの使い方、条件に基づく行と列の抽出方法について解説します。

 

 インデックスの設定とリセット

以下のコードは、データフレームの特定の列をインデックスに設定し、その後、インデックスをリセットする方法を示しています。

# インデックスの設定
df2.set_index('group', inplace=True)
print(df2)

print()

# インデックスのリセット
df2.reset_index(inplace=True)
print(df2)

 

以下、実行結果です。

       column1  column2
group                  
A           12        8
B           15        5
A           10        7
B           17        9
A           19        4

  group  column1  column2
0     A       12        8
1     B       15        5
2     A       10        7
3     B       17        9
4     A       19        4

 

 行と列のスライシング

以下のコードは、データフレームの特定の行と列をスライスする方法を示しています。

# 行のスライシング
sliced_rows = df[1:3]
print(sliced_rows)
print()

# 列のスライシング
sliced_columns = df.loc[:, 'column1':'user_id']
print(sliced_columns)
print()

# 行と列のスライシング
sliced_rows_columns = df.loc[1:3, 'column1':'user_id']
print(sliced_rows_columns)

 

以下、実行結果です。

      name  age  salary   department    status  column1  column2 group_column  \
1      Bob   32   60000      Finance  inactive       15        5            B   
2  Charlie   37   75000  Engineering    active       10        7            A   

   user_id  last_login  
1        2  2024-04-30  
2        3  2024-05-05  

   column1  column2 group_column  user_id
0       12        8            A        1
1       15        5            B        2
2       10        7            A        3
3       17        9            B        4
4       19        4            A        5

   column1  column2 group_column  user_id
1       15        5            B        2
2       10        7            A        3
3       17        9            B        4

 

 .locと.ilocの使い方

.loc.ilocは、データフレームから特定の行や列を抽出するための便利な方法です。

まず、.locを使ったスライシング(ラベルベース)です。

以下、コードです。

# .locを使ったスライシング(ラベルベース)
df_loc = df.loc[1:3, 'column1':'user_id']

print(df_loc)

 

以下、実行結果です。

   column1  column2 group_column  user_id
1       15        5            B        2
2       10        7            A        3
3       17        9            B        4

 

次に、.ilocを使ったスライシング(位置ベース)です。

以下、コードです。

# .ilocを使ったスライシング(位置ベース)
df_iloc = df.iloc[1:3, 5:9] 

print(df_iloc)

 

以下、実行結果です。

   column1  column2 group_column  user_id
1       15        5            B        2
2       10        7            A        3

 

 条件に基づく行と列の抽出

以下のコードは、条件に基づいて特定の行と列を抽出する方法を示しています。

# 条件に基づく行と列の抽出
filtered_df = df.loc[df['column1'] > 12, ['column1', 'column2']]

print(filtered_df)

 

以下、実行結果です。

   column1  column2
1       15        5
3       17        9
4       19        4

 

これらの方法を使うことで、データフレームから必要な部分だけを効率的に抽出することができます。データ分析や前処理において非常に役立つテクニックです。

 

データの集計とグループ化

Pandasを使うと、データの集計やグループ化が簡単に行えます。

ここでは、データの基本的な集計メソッド、groupbyを使ったデータのグループ化、そして集約関数の適用とカスタム集約について解説します。

 

 データの集計メソッド(sum, mean, countなど)

Pandasは、データの集計を行うための多くのメソッドを提供しています。

以下のコード例では、summeancountメソッドを使って列の集計を行います。

# データの集計
sum_value = df['column1'].sum()
mean_value = df['column1'].mean()
count_value = df['column1'].count()

print(f'Sum: {sum_value}, Mean: {mean_value}, Count: {count_value}')

 

以下、実行結果です。

Sum: 73, Mean: 14.6, Count: 5

 

 `groupby`を使ったデータのグループ化

groupbyメソッドを使うと、特定の列に基づいてデータをグループ化し、各グループに対して集計を行うことができます。

以下のコード例では、group_columnに基づいてデータをグループ化し、各グループの合計を計算します。

# グループ化と集計
grouped_df = df[
    ['group_column','salary','column1','column1']
    ].groupby('group_column').sum()

print(grouped_df)

 

以下、実行結果です。

              salary  column1  column1
group_column                          
A             187000       41       41
B             118000       32       32

 

 集約関数の適用とカスタム集約

groupbyメソッドとaggメソッドを組み合わせることで、複数の集約関数を同時に適用することができます。

以下のコード例では、column1合計column2平均を計算するカスタム集約を行います。

# カスタム集約
custom_agg = df.groupby('group_column').agg({'column1': 'sum', 'column2': 'mean'})

print(custom_agg)

 

以下、実行結果です。

              column1   column2
group_column                   
A                  41  6.333333
B                  32  7.000000

 

これらのテクニックを使うことで、データの集計とグループ化を効率的に行い、データ分析をより深く理解することができます。

 

よくある問題とその対策

データを扱う際には、様々な問題に直面することがあります。

ここでは、よくある問題とその対策について解説します。

 

 NaN値の扱い

データに欠損値NaN)が含まれている場合、適切に処理する必要があります。

以下のコード例では、NaN値の除去と置換方法を示しています。

# サンプルデータフレームの作成
data = {
    'column1': [1, 2, None, 4, 5],
    'column2': [None, 2, 3, None, 5]
}
df3 = pd.DataFrame(data)

# NaN値の除去
df3.dropna(inplace=True)
print("NaN値の除去後:")
print(df3)
print()

# サンプルデータフレームの再作成(前の操作でNaNが削除されたため)
df3 = pd.DataFrame(data)

# NaN値の置換
df3.fillna(0, inplace=True)
print("NaN値の置換後:")
print(df3)

 

以下、実行結果です。

NaN値の除去後:
   column1  column2
1      2.0      2.0
4      5.0      5.0

NaN値の置換後:
   column1  column2
0      1.0      0.0
1      2.0      2.0
2      0.0      3.0
3      4.0      0.0
4      5.0      5.0

 

 データ型の変換と整形

データ型が適切でない場合、計算や処理に問題が生じることがあります。

以下のコード例では、データ型の変換方法を示しています。

# サンプルデータフレームの作成
data = {
    'column': [1.0, 2.5, 3.8, 4.1, 5.6]
}
df4 = pd.DataFrame(data)

print("データ型の変換前:")
print(df4)
print()

# データ型の変換
df4['column'] = df4['column'].astype(int)
print("データ型の変換後:")
print(df4)

 

以下、実行結果です。

データ型の変換前:
   column
0     1.0
1     2.5
2     3.8
3     4.1
4     5.6

データ型の変換後:
   column
0       1
1       2
2       3
3       4
4       5

 

 大規模データの扱い

大規模データを扱う際には、一度に全てのデータを読み込むのではなく、チャンクごとにデータを処理することが推奨されます。

これにより、メモリの使用量を抑え、効率的にデータを処理することができます。

 

簡単な例を示します。

先ず、3つの変数を持つ大規模データセットを生成します。このデータセットには、valuecategorystatusという列が含まれています。

以下、コードです。

import pandas as pd
import numpy as np

# サンプル大規模データの作成
np.random.seed(0)
data = {
    'value': np.random.randint(0, 100, size=100000),
    'category': np.random.choice(['A', 'B', 'C'], size=100000),
    'status': np.random.choice(['active', 'inactive'], size=100000)
}

large_df = pd.DataFrame(data)
large_df.to_csv('large_data.csv', index=False)

 

データをチャンクごとに読み込み、特定の条件を満たす行をフィルタリングし、さらにカテゴリーごとvalue平均値を計算します。その後、全体の平均を求めます。

以下、コードです。

import pandas as pd

# 初期化
total_sum = 0
total_count = 0

# 処理するための関数を定義
def process(chunk):
    global total_sum, total_count
    
    # 例:特定の条件に基づいてフィルタリング(value > 50 かつ statusが'active')
    filtered_chunk = chunk[(chunk['value'] > 50) &amp; (chunk['status'] == 'active')]
    
    # カテゴリーごとのvalueの合計とカウントを計算
    sum_per_category = filtered_chunk.groupby('category')['value'].sum()
    count_per_category = filtered_chunk.groupby('category')['value'].count()
    
    # 合計とカウントを累積
    total_sum += sum_per_category
    total_count += count_per_category

# 大規模データの一部読み込み
chunk_size = 10000
for chunk in pd.read_csv('large_data.csv', chunksize=chunk_size):
    process(chunk)

# 全体の平均を計算
overall_mean = total_sum / total_count
print(overall_mean)

 

チャンクに対してvalueが50より大きく、かつstatusactiveの行をフィルタリングし、フィルタリングされたデータのカテゴリーごとのvalueの合計とカウントを累積して、最終的に全体の平均を求めます。

以下、実行結果です。

category
A    74.815099
B    75.085686
C    75.144033
Name: value, dtype: float64

 

このようにして、大規模データをチャンクごとに処理し、全体の平均を効率的に計算することができます。

 

まとめ

Pandasを使ったデータ抽出の基本から応用までをカバーしました。

フィルタリング列選択の技術を習得することで、データ分析の効率が大幅に向上します。

ぜひ、これらのテクニックを実際のデータ分析で活用してみてください。