ブラケット構文によるデータ選択
pandasでの列選択にはブラケットの使い方に注意が必要です。複数列を選択する際は二重ブラケットが必須となります。
# 複数列の選択(DataFrameを返す)
result = dataset[["col_a", "col_b", "col_c"]]
# 単一列の選択(Seriesを返す)
series_data = dataset["col_a"]
# 単一列をDataFrameとして取得
frame_data = dataset[["col_a"]]
データ型の変換手法
列のデータ型を変換するには複数のアプローチがあります。欠損値の扱いに注意が必要です。
# astypeを使用した変換
dataset.loc[:, "numeric_col"] = dataset["text_col"].astype("float")
# mapとlambdaを組み合わせた変換
dataset.loc[:, "numeric_col"] = dataset["text_col"].map(lambda v: float(v) if pd.notna(v) else 0)
# DataFrame全体の型変換(欠損値があると失敗する場合あり)
converted = pd.DataFrame(dataset, dtype=np.float64)
DataFrameの結合操作
横方向の結合
# 内部結合
merged = pd.merge(left=table_a, right=table_b, on="common_key")
# 外部結合
outer_merged = pd.merge(table_a, table_b, how="outer", left_on="id_a", right_on="id_b")
# クロス結合(デカルト積)
table_a["_merge_key"] = 1
table_b["_merge_key"] = 1
cross_result = pd.merge(table_a, table_b)
縦方向の結合
# 複数ファイルの読み込みと結合
import glob
file_list = glob.glob("./data/*.csv")
dataframes = [pd.read_csv(f) for f in file_list]
combined = pd.concat(dataframes, ignore_index=True)
行方向の反復処理
大規模データでのループ処理は避けるべきですが、必要な場合は以下の方法があります。
# zipを使用した複数列の同時走査
for val_x, val_y in zip(dataset["X"], dataset["Y"]):
process(val_x, val_y)
# 辞書形式での行アクセス(メモリ効率は良くない)
for record in dataset.to_dict("records"):
print(record["column_name"])
並べ替えと重複除去
# 単一列での降順ソート
sorted_df = dataset.sort_values(by="revenue", ascending=False)
# 複合条件でのソート
sorted_df = dataset.sort_values(by=["category", "priority"], ascending=[True, False])
# 重複除去とソートの組み合わせ
unique_sorted = dataset.drop_duplicates().sort_values(by=["date", "amount"])
インデックスの操作
# 時系列データのインデックス設定
dataset.set_index(pd.to_datetime(dataset["timestamp"]), inplace=True)
# インデックスのリセットと連番振り直し
dataset.reset_index(drop=True, inplace=True)
# 逆順への並べ替え
dataset = dataset.iloc[::-1].reset_index(drop=True)
列名の変更
# 辞書による個別変更
dataset.rename(columns={"old_name": "new_name"}, inplace=True)
# 関数による一括変更
dataset.rename(columns=lambda x: x.strip().lower(), inplace=True)
# 文字列操作による一括変更
dataset.columns = dataset.columns.str.replace("_", "-")
統計情報の取得
# 基本統計量
dataset.describe()
# データ型情報
dataset.dtypes
dataset.info()
# カテゴリ列の集計
dataset["status"].value_counts()
dataset["category"].unique()
# 相関・共分散
dataset.corr() # 相関係数行列
dataset.cov() # 共分散行列
データの抽出(loc/iloc)
# 行の選択(ラベルベース)
dataset.loc["2024-01-01"] # 単一行
dataset.loc["2024-01-01":"2024-01-31"] # 範囲指定
# 列の選択
dataset.loc[:, "column_name"] # 単一列(Series)
dataset.loc[:, ["col_a", "col_b"]] # 複数列(DataFrame)
# 条件付き選択
filtered = dataset.loc[
(dataset["region"] == "東京") &
(dataset["amount"] > 10000),
:
]
条件に基づくデータクエリ
# 複合条件のフィルタリング
result = dataset.loc[
(dataset["temperature"] <= 30) &
(dataset["humidity"] >= 40) &
(dataset["weather"] == "晴れ"),
:
]
# カスタム関数によるフィルタリング
def is_weekend(record):
return pd.to_datetime(record["date"]).weekday() >= 5
weekend_data = dataset[dataset.apply(is_weekend, axis=1)]
新規列の追加
# 演算による列追加
dataset["difference"] = dataset["max_temp"] - dataset["min_temp"]
# applyによる複雑な計算
def categorize_temp(row):
if row["max_temp"] > 35:
return "猛暑"
elif row["min_temp"] < 0:
return "厳寒"
return "普通"
dataset["temp_category"] = dataset.apply(categorize_temp, axis=1)
# assignによる複数列の一括追加
dataset = dataset.assign(
fahrenheit_high=lambda x: x["max_temp"] * 9/5 + 32,
fahrenheit_low=lambda x: x["min_temp"] * 9/5 + 32
)
行の追加
# concatによる結合
new_rows = pd.DataFrame([[5, 6], [7, 8]], columns=["A", "B"])
combined = pd.concat([original_df, new_rows], ignore_index=True)
欠損値の処理
# 欠損値の確認
dataset.isnull().sum()
# 欠損値を含む行の選択
valid_data = dataset[dataset["score"].notna()]
# 欠損値の削除
dataset.dropna(subset=["essential_col"], inplace=True)
# 欠損値の埋め方
dataset["score"].fillna(0, inplace=True) # 定数で埋める
dataset["name"].fillna(method="ffill", inplace=True) # 前の値で埋める
時系列データの処理
# 文字列から日時型への変換
dataset["datetime"] = pd.to_datetime(dataset["date_string"])
# 特定フォーマットでの解析
dataset["parsed"] = pd.to_datetime(
dataset["log_time"],
format="%d/%b/%Y:%H:%M:%S"
)
# 時系列インデックスの操作
dataset.loc["2024-01"] # 月単位の選択
dataset.loc["2024-01-01":"2024-01-07"] # 範囲選択
# リサンプリング
hourly = dataset.resample("H")["value"].agg(["sum", "mean"])
daily = dataset.resample("D")["value"].sum()
# 日時コンポーネントの抽出
dataset["year_month"] = dataset["datetime"].dt.strftime("%Y%m")
dataset["date_only"] = dataset["datetime"].dt.date
SeriesからDataFrameへの変換
# reset_indexを使用
df_from_series = series_data.reset_index()
# 辞書からの構築
df_from_series = pd.DataFrame({
"timestamp": series_data.index,
"measurement": series_data.values
})
文字列処理
# 文字列メソッドの連鎖(strアクセサが必要)
dataset["cleaned"] = (
dataset["raw_text"]
.str.replace("[年月日]", "", regex=True)
.str.strip()
)
# 部分文字列の抽出
dataset["prefix"] = dataset["code"].str[:3]
# 正規表現による抽出
dataset["extracted"] = dataset["text"].str.extract(r"(\d{4})")
GroupByによる集計
# 基本集計
grouped = dataset.groupby("category")["amount"].sum()
# 複合キーでの集計
grouped = dataset.groupby(["year", "month"]).agg({
"revenue": "sum",
"count": "mean",
"std_dev": "std"
})
# インデックスを保持しない集計
grouped = dataset.groupby("region", as_index=False).agg({
"sales": ["sum", "mean", "count"]
})
# グループごとのカスタム処理
def normalize_group(group_df):
min_val = group_df["rating"].min()
max_val = group_df["rating"].max()
group_df["normalized"] = (group_df["rating"] - min_val) / (max_val - min_val)
return group_df
normalized = dataset.groupby("user_id").apply(normalize_group)
多層インデックス(MultiIndex)
# 多層インデックスの作成
dataset.set_index(["company", "date"], inplace=True)
# 階層的なデータアクセス
dataset.loc["A社"] # 第1階層
dataset.loc[:, "2024-01-01"] # 第2階層
dataset.loc[("A社", "2024-01-01"), :] # 両階層
# unstackによるピボット
pivoted = dataset.unstack(level="date")
apply系メソッドの使い分け
| メソッド | 適用対象 | 関数の引数 |
|---|---|---|
| map | Series | 各要素の値 |
| apply | Series/DataFrame | Series全体(axis指定時) |
| applymap | DataFrame | 各要素の値 |
# map: 値→値の変換
dataset["mapped"] = dataset["code"].map({"A": "優良", "B": "良"})
# apply: 行・列方向の処理
dataset["processed"] = dataset.apply(
lambda row: process(row["col_a"], row["col_b"]),
axis=1
)
# applymap: 要素ごとの処理
dataset[numeric_cols] = dataset[numeric_cols].applymap(int)
データのピボット操作
# stack/unstack
stacked = dataset.stack() # 列をインデックスに
unstacked = dataset.unstack() # インデックスを列に
# pivotによる整形
pivoted = dataset.pivot(
index="date",
columns="category",
values="amount"
)
# pivot_tableによる集計付きピボット
summary = pd.pivot_table(
dataset,
values="sales",
index="region",
columns="product",
aggfunc="sum",
fill_value=0
)
Excelファイルの入出力
# 読み込み
df_from_excel = pd.read_excel("./data/input.xlsx", sheet_name="Sheet1")
# 複数シートの読み込み
all_sheets = pd.read_excel("./data/input.xlsx", sheet_name=None)
for sheet_name, sheet_df in all_sheets.items():
process(sheet_df)
# 書き出し
dataset.to_excel("./output/result.xlsx", index=False, engine="openpyxl")
# 列順序の調整後に書き出し
cols = dataset.columns.tolist()
cols.insert(cols.index("id") + 1, cols.pop(cols.index("name")))
dataset[cols].to_excel("./output/reordered.xlsx", index=False)