⚡ STEP 9: カラム操作と関数①
pyspark.sql.functionsで文字列操作と数値計算をマスターする
📋 このステップで学ぶこと
- col()とF(pyspark.sql.functions)の基本
- 文字列操作(concat、substring、split)
- 数値計算(round、abs、sqrt)
- 練習問題10問
学習時間の目安: 2.5時間
🎯 1. col()とpyspark.sql.functions
1-1. pyspark.sql.functionsとは?
pyspark.sql.functionsは、DataFrameの列を操作するための豊富な関数群です。文字列処理、数値計算、日付操作など、様々な関数が用意されています。
# インポート方法 # 方法1: 個別にインポート from pyspark.sql.functions import col, concat, upper, lower # 方法2: まとめてインポート(推奨) from pyspark.sql import functions as F # 方法3: 全てインポート(非推奨) from pyspark.sql.functions import *
import pyspark.sql.functions as Fが最も一般的です。
F.col()、F.concat()のように使えて、コードが読みやすいです。
1-2. col()関数の基本
col()は、列を参照するための関数です。df.column_nameと同じ意味ですが、より柔軟に使えます。
# col()の使い方 from pyspark.sql import SparkSession from pyspark.sql.functions import col spark = SparkSession.builder.appName("Col").getOrCreate() data = [("Alice", 30), ("Bob", 25), ("Charlie", 35)] df = spark.createDataFrame(data, ["name", "age"]) # 方法1: df.column_name df.select(df.age).show() # 方法2: col("column_name") df.select(col("age")).show() # 方法3: "column_name"(文字列) df.select("age").show() # どれも同じ結果 spark.stop()
・列名にスペースや特殊文字が含まれる場合
・列名が変数に格納されている場合
・計算や関数と組み合わせる場合
# col()が必要な例 # 列名にスペースがある df.select(col("first name")).show() # 列名が変数 column_name = "age" df.select(col(column_name)).show() # 計算と組み合わせ df.select(col("age") * 2).show()
📝 2. 文字列操作:concat、substring、split
2-1. concat() – 文字列の結合
concat()は、複数の列を結合して1つの文字列にします。
# concat()の基本 from pyspark.sql import SparkSession from pyspark.sql.functions import concat, col, lit spark = SparkSession.builder.appName("Concat").getOrCreate() data = [ ("Alice", "Smith", 30), ("Bob", "Johnson", 25), ("Charlie", "Brown", 35) ] df = spark.createDataFrame(data, ["first_name", "last_name", "age"]) # 名前を結合 df_concat = df.withColumn( "full_name", concat(col("first_name"), lit(" "), col("last_name")) ) df_concat.select("first_name", "last_name", "full_name").show() spark.stop()
+----------+---------+--------------+ |first_name|last_name| full_name| +----------+---------+--------------+ | Alice| Smith| Alice Smith| | Bob| Johnson| Bob Johnson| | Charlie| Brown| Charlie Brown| +----------+---------+--------------+
lit()は、固定値(リテラル)を列として扱うための関数です。
lit(" ")は、スペース文字を列として扱います。
2-2. concat_ws() – セパレーター付き結合
# concat_ws()の使い方 from pyspark.sql.functions import concat_ws # セパレーターを指定して結合 df_concat_ws = df.withColumn( "full_name", concat_ws(" ", col("first_name"), col("last_name")) ) df_concat_ws.select("full_name").show() # カンマ区切り df_csv = df.withColumn( "info", concat_ws(", ", col("first_name"), col("last_name"), col("age").cast("string")) ) df_csv.select("info").show()
+-------------------+ | info| +-------------------+ | Alice, Smith, 30| | Bob, Johnson, 25 | |Charlie, Brown, 35 | +-------------------+
2-3. substring() – 部分文字列の抽出
substring()は、文字列の一部を切り出します。
# substring()の基本 from pyspark.sql.functions import substring spark = SparkSession.builder.appName("Substring").getOrCreate() data = [("ABC123", ), ("DEF456", ), ("GHI789", )] df = spark.createDataFrame(data, ["code"]) # 最初の3文字を抽出(位置は1から始まる) df_sub = df.withColumn("prefix", substring(col("code"), 1, 3)) # 4文字目から3文字を抽出 df_sub = df_sub.withColumn("suffix", substring(col("code"), 4, 3)) df_sub.show() spark.stop()
+------+------+------+ | code|prefix|suffix| +------+------+------+ |ABC123| ABC| 123| |DEF456| DEF| 456| |GHI789| GHI| 789| +------+------+------+
Sparkの文字列位置は1から始まる(Pythonは0から始まる)
substring(col, 1, 3) → 1文字目から3文字
2-4. split() – 文字列の分割
split()は、文字列を配列に分割します。
# split()の基本 from pyspark.sql.functions import split spark = SparkSession.builder.appName("Split").getOrCreate() data = [("Alice Smith", ), ("Bob Johnson", ), ("Charlie Brown", )] df = spark.createDataFrame(data, ["full_name"]) # スペースで分割 df_split = df.withColumn("name_array", split(col("full_name"), " ")) df_split.show(truncate=False) # 配列の要素を取得(0から始まる) df_names = df_split.withColumn("first_name", col("name_array")[0]) \ .withColumn("last_name", col("name_array")[1]) df_names.select("first_name", "last_name").show() spark.stop()
+--------------+------------------+ |full_name |name_array | +--------------+------------------+ |Alice Smith |[Alice, Smith] | |Bob Johnson |[Bob, Johnson] | |Charlie Brown |[Charlie, Brown] | +--------------+------------------+
2-5. その他の文字列関数
| 関数 | 説明と例 |
|---|---|
upper() |
大文字に変換F.upper(col("name")) |
lower() |
小文字に変換F.lower(col("name")) |
trim() |
前後の空白を削除F.trim(col("name")) |
ltrim() |
左側の空白を削除F.ltrim(col("name")) |
rtrim() |
右側の空白を削除F.rtrim(col("name")) |
length() |
文字列の長さF.length(col("name")) |
replace() |
文字列の置換F.replace(col("text"), "old", "new") |
# 文字列関数の実践例 from pyspark.sql.functions import upper, lower, trim, length spark = SparkSession.builder.appName("StrFunctions").getOrCreate() data = [(" Alice ", ), (" BOB ", ), (" Charlie ", )] df = spark.createDataFrame(data, ["name"]) # 複数の文字列操作を連続で適用 df_clean = df.withColumn("name_upper", upper(trim(col("name")))) \ .withColumn("name_lower", lower(trim(col("name")))) \ .withColumn("name_length", length(trim(col("name")))) df_clean.show(truncate=False) spark.stop()
+----------+----------+----------+-----------+ |name |name_upper|name_lower|name_length| +----------+----------+----------+-----------+ | Alice |ALICE |alice |5 | | BOB |BOB |bob |3 | | Charlie |CHARLIE |charlie |7 | +----------+----------+----------+-----------+
🔢 3. 数値計算:round、abs、sqrt
3-1. 基本的な算術演算
# 算術演算の基本 from pyspark.sql import SparkSession from pyspark.sql.functions import col spark = SparkSession.builder.appName("Arithmetic").getOrCreate() data = [(10, ), (20, ), (30, )] df = spark.createDataFrame(data, ["value"]) # 加算、減算、乗算、除算 df_calc = df.withColumn("add_10", col("value") + 10) \ .withColumn("sub_5", col("value") - 5) \ .withColumn("mul_2", col("value") * 2) \ .withColumn("div_3", col("value") / 3) df_calc.show() spark.stop()
+-----+------+-----+-----+------------------+ |value|add_10|sub_5|mul_2| div_3| +-----+------+-----+-----+------------------+ | 10| 20| 5| 20| 3.333333333333...| | 20| 30| 15| 40| 6.666666666666...| | 30| 40| 25| 60| 10.0| +-----+------+-----+-----+------------------+
3-2. round() – 四捨五入
round()は、数値を指定した桁数で四捨五入します。
# round()の使い方 from pyspark.sql.functions import round as spark_round spark = SparkSession.builder.appName("Round").getOrCreate() data = [(3.14159, ), (2.71828, ), (1.41421, )] df = spark.createDataFrame(data, ["value"]) # 小数点以下2桁に四捨五入 df_round = df.withColumn("rounded_2", spark_round(col("value"), 2)) # 小数点以下0桁(整数に) df_round = df_round.withColumn("rounded_0", spark_round(col("value"), 0)) df_round.show() spark.stop()
+-------+---------+---------+ | value|rounded_2|rounded_0| +-------+---------+---------+ |3.14159| 3.14| 3.0| |2.71828| 2.72| 3.0| |1.41421| 1.41| 1.0| +-------+---------+---------+
Pythonの組み込み関数round()と名前が被るため、
from pyspark.sql.functions import round as spark_round
のように別名でインポートすることを推奨します。
3-3. abs() – 絶対値
abs()は、数値の絶対値を返します。
# abs()の使い方 from pyspark.sql.functions import abs as spark_abs spark = SparkSession.builder.appName("Abs").getOrCreate() data = [(10, ), (-20, ), (30, ), (-40, )] df = spark.createDataFrame(data, ["value"]) # 絶対値を計算 df_abs = df.withColumn("absolute", spark_abs(col("value"))) df_abs.show() spark.stop()
+-----+--------+ |value|absolute| +-----+--------+ | 10| 10| | -20| 20| | 30| 30| | -40| 40| +-----+--------+
3-4. sqrt() – 平方根
sqrt()は、数値の平方根を計算します。
# sqrt()の使い方 from pyspark.sql.functions import sqrt spark = SparkSession.builder.appName("Sqrt").getOrCreate() data = [(4, ), (9, ), (16, ), (25, )] df = spark.createDataFrame(data, ["value"]) # 平方根を計算 df_sqrt = df.withColumn("square_root", sqrt(col("value"))) df_sqrt.show() spark.stop()
+-----+-----------+ |value|square_root| +-----+-----------+ | 4| 2.0| | 9| 3.0| | 16| 4.0| | 25| 5.0| +-----+-----------+
3-5. その他の数値関数
| 関数 | 説明と例 |
|---|---|
ceil() |
切り上げF.ceil(col("value")) |
floor() |
切り捨てF.floor(col("value")) |
pow() |
累乗F.pow(col("value"), 2) → 2乗 |
exp() |
指数関数(e^x)F.exp(col("value")) |
log() |
自然対数F.log(col("value")) |
log10() |
常用対数F.log10(col("value")) |
sin(), cos(), tan() |
三角関数F.sin(col("angle")) |
# 数値関数の実践例 from pyspark.sql.functions import ceil, floor, pow spark = SparkSession.builder.appName("MathFunctions").getOrCreate() data = [(3.7, ), (5.2, ), (8.9, )] df = spark.createDataFrame(data, ["value"]) # 切り上げ、切り捨て、2乗 df_math = df.withColumn("ceiling", ceil(col("value"))) \ .withColumn("flooring", floor(col("value"))) \ .withColumn("squared", pow(col("value"), 2)) df_math.show() spark.stop()
+-----+-------+--------+------------------+ |value|ceiling|flooring| squared| +-----+-------+--------+------------------+ | 3.7| 4| 3|13.690000000000001| | 5.2| 6| 5|27.040000000000003| | 8.9| 9| 8| 79.21000000000001| +-----+-------+--------+------------------+
📝 練習問題
名前を大文字に変換するカラム”name_upper”を追加してください。データ: [(“alice”, ), (“bob”, ), (“charlie”, )]
from pyspark.sql import SparkSession from pyspark.sql.functions import upper spark = SparkSession.builder.appName("Q1").getOrCreate() data = [("alice", ), ("bob", ), ("charlie", )] df = spark.createDataFrame(data, ["name"]) df_upper = df.withColumn("name_upper", upper(df.name)) df_upper.show() spark.stop()
“first_name”と”last_name”を結合して”full_name”カラムを作成してください。データ: [(“Alice”, “Smith”), (“Bob”, “Johnson”)]
from pyspark.sql.functions import concat, lit spark = SparkSession.builder.appName("Q2").getOrCreate() data = [("Alice", "Smith"), ("Bob", "Johnson")] df = spark.createDataFrame(data, ["first_name", "last_name"]) df_full = df.withColumn( "full_name", concat(df.first_name, lit(" "), df.last_name) ) df_full.show() spark.stop()
数値を小数点以下1桁に四捨五入してください。データ: [(3.14159, ), (2.71828, )]
from pyspark.sql.functions import round as spark_round spark = SparkSession.builder.appName("Q3").getOrCreate() data = [(3.14159, ), (2.71828, )] df = spark.createDataFrame(data, ["value"]) df_rounded = df.withColumn("rounded", spark_round(df.value, 1)) df_rounded.show() spark.stop()
負の数を含むデータの絶対値を計算してください。データ: [(10, ), (-20, ), (30, ), (-40, )]
from pyspark.sql.functions import abs as spark_abs spark = SparkSession.builder.appName("Q4").getOrCreate() data = [(10, ), (-20, ), (30, ), (-40, )] df = spark.createDataFrame(data, ["value"]) df_abs = df.withColumn("absolute", spark_abs(df.value)) df_abs.show() spark.stop()
“ABC-123″のような文字列から、”-“で分割して”prefix”と”suffix”カラムを作成してください。
from pyspark.sql.functions import split spark = SparkSession.builder.appName("Q5").getOrCreate() data = [("ABC-123", ), ("DEF-456", )] df = spark.createDataFrame(data, ["code"]) df_split = df.withColumn("code_array", split(df.code, "-")) \ .withColumn("prefix", split(df.code, "-")[0]) \ .withColumn("suffix", split(df.code, "-")[1]) df_split.select("code", "prefix", "suffix").show() spark.stop()
文字列の長さを計算するカラム”name_length”を追加してください。データ: [(“Alice”, ), (“Bob”, ), (“Charlie”, )]
from pyspark.sql.functions import length spark = SparkSession.builder.appName("Q6").getOrCreate() data = [("Alice", ), ("Bob", ), ("Charlie", )] df = spark.createDataFrame(data, ["name"]) df_length = df.withColumn("name_length", length(df.name)) df_length.show() spark.stop()
数値の平方根を計算してください。データ: [(4, ), (9, ), (16, ), (25, )]
from pyspark.sql.functions import sqrt spark = SparkSession.builder.appName("Q7").getOrCreate() data = [(4, ), (9, ), (16, ), (25, )] df = spark.createDataFrame(data, ["value"]) df_sqrt = df.withColumn("square_root", sqrt(df.value)) df_sqrt.show() spark.stop()
前後の空白を削除し、大文字に変換してください。データ: [(” alice “, ), (” bob “, )]
from pyspark.sql.functions import trim, upper spark = SparkSession.builder.appName("Q8").getOrCreate() data = [(" alice ", ), (" bob ", )] df = spark.createDataFrame(data, ["name"]) df_clean = df.withColumn("name_clean", upper(trim(df.name))) df_clean.show(truncate=False) spark.stop()
数値を2乗した結果を小数点以下2桁に四捨五入してください。データ: [(3.5, ), (4.7, ), (5.2, )]
from pyspark.sql.functions import pow, round as spark_round spark = SparkSession.builder.appName("Q9").getOrCreate() data = [(3.5, ), (4.7, ), (5.2, )] df = spark.createDataFrame(data, ["value"]) df_calc = df.withColumn( "squared_rounded", spark_round(pow(df.value, 2), 2) ) df_calc.show() spark.stop()
“email@example.com”のようなメールアドレスから、”@”の前の部分(ユーザー名)を抽出してください。
from pyspark.sql.functions import split spark = SparkSession.builder.appName("Q10").getOrCreate() data = [("alice@example.com", ), ("bob@test.com", )] df = spark.createDataFrame(data, ["email"]) df_username = df.withColumn("username", split(df.email, "@")[0]) df_username.show(truncate=False) spark.stop()
📝 STEP 9 のまとめ
・pyspark.sql.functionsをFとしてインポート
・concat()で文字列結合、split()で分割
・upper()、lower()で大文字小文字変換
・trim()で空白削除、length()で長さ取得
・round()で四捨五入、abs()で絶対値
・sqrt()で平方根、pow()で累乗
pyspark.sql.functionsには、100以上の関数が用意されています。
全てを覚える必要はなく、必要な時に公式ドキュメントを参照すればOKです。
よく使う関数(concat、split、round、abs)は自然と覚えます!
次のSTEP 10では、「カラム操作と関数②」を学びます。
日付操作、NULL処理、条件分岐など、さらに実用的な関数をマスターしましょう!
学習メモ
ビッグデータ処理(Apache Spark) - Step 9