Polarsは列指向 - 行方向の平均を計算する方法
pandasからPolarsに移行してきた方は、関数の引数にaxis
を指定することが一般的で、ついPolarsでも同じようにしてしまいがちです(私もその一人です)。しかし、Polarsは 列指向(column-oriented) のデータフレームライブラリであるため、行方向の計算には少し工夫が必要です。
この記事では、Polarsで行方向に平均を取る方法について、pandasとの違いを交えながら解説します。
pandasでの行方向の平均の取り方
まずは、pandasで行方向に平均を取る方法を確認しましょう。
import pandas as pd
# サンプルのデータフレームを作成
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
})
# 行方向に平均を計算し、新しい列として追加
df['row_mean'] = df.mean(axis=1)
print(df)
出力結果:
A B C row_mean
0 1 4 7 4.0
1 2 5 8 5.0
2 3 6 9 6.0
pandasでは、df.mean(axis=1)
とすることで、行方向(各行の値)に対して平均を計算しています。
Polarsでの行方向の平均の取り方
一方、Polarsではどうでしょうか。
列指向と行指向
Polarsは列指向の設計となっており、基本的に列に対する操作が中心です。そのため、行方向の計算を行う場合、専用の関数を使用する必要があります。
mean_horizontal
関数を使用する
行方向に計算を行うために、Polarsには mean_horizontal
や sum_horizontal
といった「*_horizontal」関数が用意されています。
import polars as pl
# サンプルのデータフレームを作成
df = pl.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9]
})
# 行方向に平均を計算し、新しい列として追加
df = df.with_columns(
pl.mean_horizontal(pl.all()).alias("row_mean")
)
print(df)
出力結果:
shape: (3, 4)
┌─────┬─────┬─────┬─────────┐
│ A ┆ B ┆ C ┆ row_mean│
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 │
╞═════╪═════╪═════╪═════════╡
│ 1 ┆ 4 ┆ 7 ┆ 4.0 │
│ 2 ┆ 5 ┆ 8 ┆ 5.0 │
│ 3 ┆ 6 ┆ 9 ┆ 6.0 │
└─────┴─────┴─────┴─────────┘
pl.mean_horizontal(pl.all())
により、全ての列に対して行ごとの平均を計算し、新しい列 row_mean
として追加しています。
特定の列のみを対象とする場合
特定の列のみを平均したい場合、pl.all()
の代わりに列を指定します。
# 'A' と 'B' 列のみを平均
df = df.with_columns(
pl.mean_horizontal(['A', 'B']).alias("mean_AB")
)
print(df)
出力結果:
shape: (3, 5)
┌─────┬─────┬─────┬─────────┬────────┐
│ A ┆ B ┆ C ┆ row_mean┆ mean_AB│
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 ┆ f64 │
╞═════╪═════╪═════╪═════════╪════════╡
│ 1 ┆ 4 ┆ 7 ┆ 4.0 ┆ 2.5 │
│ 2 ┆ 5 ┆ 8 ┆ 5.0 ┆ 3.5 │
│ 3 ┆ 6 ┆ 9 ┆ 6.0 ┆ 4.5 │
└─────┴─────┴─────┴─────────┴────────┘
このように、対象の列をリストで指定することで、その列に対してのみ計算を行います。
列の型に注意
Polarsはデータの型に厳密です。もし文字列型の列など、数値計算に適さない型の列が含まれている場合、エラーが発生します。そのような場合は、計算に含める列を数値型のみに限定する必要があります。
たとえば、データフレームに文字列型の列がある場合:
df = pl.DataFrame({
'A': [1, 2, 3],
'B': [4, 5, 6],
'C': [7, 8, 9],
'D': ['x', 'y', 'z'] # 文字列型の列
})
# 全ての列を対象にするとエラーになる
# df = df.with_columns(
# pl.mean_horizontal(pl.all()).alias("row_mean")
# )
# 数値型の列のみを対象にする
df = df.with_columns(
pl.mean_horizontal(pl.col(pl.Numeric)).alias("row_mean")
)
print(df)
出力結果:
shape: (3, 5)
┌─────┬─────┬─────┬─────┬─────────┐
│ A ┆ B ┆ C ┆ D ┆ row_mean│
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ str ┆ f64 │
╞═════╪═════╪═════╪═════╪═════════╡
│ 1 ┆ 4 ┆ 7 ┆ x ┆ 4.0 │
│ 2 ┆ 5 ┆ 8 ┆ y ┆ 5.0 │
│ 3 ┆ 6 ┆ 9 ┆ z ┆ 6.0 │
└─────┴─────┴─────┴─────┴─────────┘
pl.col(pl.Numeric)
を使用することで、数値型の列のみを選択しています。
まとめ
- Polarsは列指向のデータフレームライブラリであるため、行方向の計算には専用の関数が必要。
- 行方向の計算を行う場合、
mean_horizontal
やsum_horizontal
などの「*_horizontal」関数を使用する。 - pandasのように
axis=1
を指定するスタイルはPolarsには存在しない。 - 計算対象の列を明示的に指定することで、必要な計算のみを効率的に行える。
- データ型に注意し、数値型の列のみを計算に含めるようにする。
Polarsの列指向の特性を理解し、適切に行方向の計算を行うことで、より効率的なデータ処理が可能になります。
参考情報
ぜひ、Polarsでのデータ処理にチャレンジしてみてください!