STEP 9:カラム操作と関数①

⚡ 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 *
💡 推奨:F としてインポート

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()を使うべき場面

・列名にスペースや特殊文字が含まれる場合
・列名が変数に格納されている場合
計算や関数と組み合わせる場合

# 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()は、固定値(リテラル)を列として扱うための関数です。
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の文字列位置

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|
+-------+---------+---------+
⚠️ 注意:round関数の名前

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|
+-----+-------+--------+------------------+

📝 練習問題

問題 1 基礎

名前を大文字に変換するカラム”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()
問題 2 基礎

“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()
問題 3 基礎

数値を小数点以下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()
問題 4 応用

負の数を含むデータの絶対値を計算してください。データ: [(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()
問題 5 応用

“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()
問題 6 応用

文字列の長さを計算するカラム”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()
問題 7 応用

数値の平方根を計算してください。データ: [(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()
問題 8 発展

前後の空白を削除し、大文字に変換してください。データ: [(” 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()
問題 9 発展

数値を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()
問題 10 発展

“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.functionsFとしてインポート
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

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE