行インデックスの操作
import pandas as pd
# サンプルデータを作成
data = {
'col1': [0.776520, 0.130550, 0.995216, 0.253985],
'col2': [0.093637, 0.682061, 0.959426, 0.161841],
'col3': [0.819028, 0.102499, 0.337403, 0.536915],
'col4': [0.304640, 0.782682, 0.897070, 0.269828]
}
df_data = pd.DataFrame(data)
# インデックスと列名を変更
df_data.index = pd.Index(list('WXYZ'))
df_data.columns = pd.Index(list('ABCD'))
print(df_data)
日付をインデックスに設定する
import pandas as pd
# サンプルデータ('date_col'列があると仮定)
sample_data = {
'date_col': ['2023-01-01', '2023-01-02', '2023-01-03'],
'value_col': [100, 200, 300]
}
df_data = pd.DataFrame(sample_data)
# 'date_col'列をdatetime型に変換し、インデックスに設定
df_data['date_col'] = pd.to_datetime(df_data['date_col'])
df_data.set_index('date_col', inplace=True)
print(df_data)
import pandas as pd
# DataFrameコンストラクタを呼び出す
df_time = pd.DataFrame()
# 6つのタイムスタンプを作成
df_time['timestamp'] = pd.date_range('2/5/2019', periods = 6, freq ='2H')
print(df_time['timestamp']) # DataFrameを表示
# 特徴量を抽出 - 年、月、日、時、分
df_time['year_col'] = df_time['timestamp'].dt.year
df_time['month_col'] = df_time['timestamp'].dt.month
df_time['day_col'] = df_time['timestamp'].dt.day
df_time['hour_col'] = df_time['timestamp'].dt.hour
df_time['minute_col'] = df_time['timestamp'].dt.minute
# 6行を表示
df_time.head(6)
列名の変更
df_data['column_name'].rename('new_name')
df_data.rename(columns={ 'old_name':'new_name'})
行のフィルタリング
列データのフィルタリング
import numpy as np
# 欠損値を追加
df_filter.loc[2, 'age_col'] = np.nan
# 'age_col'が25またはNaNの行をフィルタリング
result_df = df_filter[df_filter['age_col'].eq(25) | df_filter['age_col'].isna()]
パラメータの説明
| メソッド |
パラメータ |
役割 |
| `eq()` |
`other` |
要素が`other`と等しいかどうかを判断 |
| `ne()` |
`other` |
要素が`other`と等しくないかどうかを判断 |
| `isin()` |
`values` |
要素が`values`リストに含まれているかどうかを判断 |
| `str.contains()` |
`pat` |
文字列が部分文字列`pat`を含むかどうかを判断 |
| `query()` |
`expr` |
文字列式を使用してデータをフィルタリング |
まとめ
- 正確な一致:`eq()`または`==`を優先的に使用
- 複数条件のフィルタリング:`&`(AND)、`|`(OR)で条件を連結し、括弧に注意
- 欠損値の処理:`isna()`または`fillna()`と組み合わせる
- 柔軟なクエリ:複雑な論理式には`query()`が適している
これらのメソッドを組み合わせることで、効率的にデータフィルタリングを完了できます。
平均値によるフィルタリング
df_avg = df_avg[df_avg.価格.lt( df_avg.価格.mean() -23)]
print(df_avg)
文字列のフィルタリング
df_str = df_str[df_str.loc[:'book_title'].str.len() < 15]
インデックスのスライス
df_slice = df_slice[:3]
# 最後の4行を選択
df_slice = df_slice[-4:]
# 2行ごとに選択し、奇数行を返す
df_slice = df_slice[1::2]
locを使った単一データの変更
df_data.loc[12345, 'category'] = '新カテゴリ'
any関数
lambda式とiloc
# 第1列の値が1より大きい行をフィルタリング
filtered_df = df_lambda[df_lambda.apply(lambda row: row.iloc[1] > 50, axis=1)]
import pandas as pd
df_iter = pd.DataFrame({
'col1': [1, 2, 3],
'col2': [4, 5, 6],
'col3': [7, 8, 9]
})
# 各行、各列をループ
for i in range(len(df_iter)): # 行インデックス
for j in range(len(df_iter.columns)): # 列インデックス
value = df_iter.iloc[i, j] # ilocで位置を指定
print(f"行[{i}], 列[{j}]: {value}")
pandasのテキスト操作
import pandas as pd
# サンプルデータ
data = {'name_col': ['Alice', 'Bob', 'Charlie', 'David'],
'email_addr': ['alice@gmail.com', 'bob@yahoo.com', 'charlie@hotmail.com', 'david@gmail.com']}
df_email = pd.DataFrame(data)
# 'email_addr'に'gmail'を含む行をフィルタリング
gmail_users_df = df_email[df_email['email_addr'].str.contains('gmail')]
print(gmail_users_df)
import pandas as pd
# サンプルデータ
data = {'name_col': ['Alice', 'Bob', 'Charlie', 'David', 'Eva123']}
df_name = pd.DataFrame(data)
# 'name_col'が'A'で始まるかどうかを検出
df_name['starts_with_a'] = df_name['name_col'].str.match('^A')
print(df_name)
is演算子
まとめ:Pandas `is` 関数クイックリファレンス
| 関数 |
役割 |
一般的な使用シーン |
| `isna()` / `isnull()` |
欠損値を検出 |
データクリーニング時に欠損値をフィルタリング |
| `notna()` / `notnull()` |
欠損値ではないかを検出 |
有効なデータをフィルタリング |
| `isin()` |
リストに含まれているかを判断 |
分類フィルタリング、データマッチング |
| `is_monotonic_increasing` |
単調増加かどうかをチェック |
時系列データの検証 |
| `str.isnumeric()` |
文字列がすべて数字かどうかを検出 |
データ形式の検証 |
| `is_unique` |
値が一意かどうかをチェック |
主キー/インデックスの検証 |
| `is_sparse` |
スパースデータを検出 |
メモリ最適化のシナリオ |
| `is_categorical()` |
分類データを検出 |
分類変数の処理 |
~ 演算子(否定)
df[~df['status'] == 'inactive']
nsmallestによる最小値の取得
apply関数
query演算子
import pandas as pd
df_query = pd.DataFrame({
'value': [1, 2, 3, 4],
'category': ['x', 'y', 'z', 'x']
})
# 'value'列が2より大きい行をフィルタリング
result = df_query.query('value > 2')
print(result)
# 'category'列が'x'または'y'の行をフィルタリング
result = df_query.query("category in ['x', 'y']")
print(result)
queryメソッドはチェーン操作をサポートしています。
rollingによるフィルタリング
# 3日間の単純移動平均を計算
df_rolling['SMA_3'] = df_rolling['price'].rolling(window=3).mean()
print(df_rolling[['price', 'SMA_3']])
# 3σを超える異常値をマーク
df_rolling['Z-Score'] = (df_rolling['price'] - df_rolling['price'].rolling(30).mean()) / df_rolling['price'].rolling(30).std()
df_rolling['Anomaly'] = df_rolling['Z-Score'].abs() > 3
sampleによるランダムサンプリング
# 列からランダムに2列を選択
selected_cols = df_sample.sample(n=2, axis=1, random_state=42)
print(selected_cols)
isnaメソッド
isnaの数をカウント
df_data.isna().sum(axis=1)
df_data.notna().sum(axis=1)
行列の合計計算によく使用されます。以下の使い方は3つのケースに分けて紹介します!
形式:np.sum(a)
np.sum(a, axis=0) ------->列の合計
np.sum(a, axis=1) ------->行の合計
注意:特に後の2つの使い方に注意してください。
dropna/fillna/maskメソッド
df_data.dropna(axis=0, how='any')
maskは条件に基づいて値を埋めることができます。
applyと型変換
# str型に変換
df_data.user_id = df_data.user_id.apply(str)
df_data.user_id = df_data.user_id.astype(int)
1. 核心的な違いのまとめ
| 特性 |
`astype()` |
`apply()` |
| 主な用途 |
列全体のデータ型を強制的に変換 |
データに対して複雑なカスタム変換を実行 |
| 操作対象 |
列全体(ベクトル化操作) |
列、行、または単一要素に対して |
| パフォーマンス |
効率的(C言語レベルの最適化) |
遅い(Pythonループ) |
| 柔軟性 |
あらかじめ定義された型変換のみをサポート |
任意のPython関数をサポート |
| 適用シーン |
単純な型変換(例:文字列→数値) |
条件判断、複数列の連携が必要な複雑なロジック |
whereメソッドによる複雑な条件での変更
df_copy = df_data.copy()
# デフォルトは合格
df_copy['math_status'] = '合格'
df_copy['math_status'] = df_copy['math_status'].where(df_copy['score'] > 60, '不合格')
catメソッド
pd.Series(['x', 'y', 'z']).str.cat(['X', 'Y', 'Z'], sep=';')
mergeメソッド
dept_df = pd.DataFrame({
'department': ['HR', 'IT', 'Finance'],
'employee_id': [101, 102, 103]
})
emp_df = pd.DataFrame({
'department': ['IT', 'Finance', 'Marketing'],
'employee_id': [102, 103, 104],
'salary': [7000, 8000, 9000]
})
# 'department'と'employee_id'で左結合
result = pd.merge(dept_df, emp_df, on=['department', 'employee_id'], how='left')
print(result)
clipメソッド
import pandas as pd
data = {'measurement': [10, 25, 5, 30, 15]}
df_clip = pd.DataFrame(data)
# 'measurement'列の値を10から20の間に制限
df_clip['measurement'].clip(lower=10, upper=20, inplace=True)
print(df_clip)
stackメソッド - ワイド形式からロング形式への変換
df_wide = pd.DataFrame(
[['Mostly cloudy', 10], ['Sunny', 12]],
index=['London', 'Oxford'],
columns=['condition', 'speed']
)
df_wide.stack()