本节来学习pyspark.sql.Column。博客中代码基于spark 2.4.4版本。不同版本函数会有不同,详细请参考官方文档。博客案例中用到的数据可以点击此处下载(提取码:2bd5)

from pyspark.sql import SparkSession
spark = SparkSession.Builder().master('local').appName('sparksqlColumn').getOrCreate()
df = spark.read.csv('../data/data.csv', header='True')
df.show(3)
+---+----+----+------+----+------+----------+-------------------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|          3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+-------------------+----+----+----+
|  0|勇士|  胜|    客|  10|    23|     0.435|              0.444|   6|  11|  27|
|  1|国王|  胜|    客|   8|    21|     0.381|0.28600000000000003|   3|   9|  27|
|  2|小牛|  胜|    主|  10|    19|     0.526|              0.462|   3|   7|  29|
+---+----+----+------+----+------+----------+-------------------+----+----+----+
only showing top 3 rows


df.printSchema()
root
 |-- _c0: string (nullable = true)
 |-- 对手: string (nullable = true)
 |-- 胜负: string (nullable = true)
 |-- 主客场: string (nullable = true)
 |-- 命中: string (nullable = true)
 |-- 投篮数: string (nullable = true)
 |-- 投篮命中率: string (nullable = true)
 |-- 3分命中率: string (nullable = true)
 |-- 篮板: string (nullable = true)
 |-- 助攻: string (nullable = true)
 |-- 得分: string (nullable = true)


df.show(3)
+---+----+----+------+----+------+----------+-------------------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|          3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+-------------------+----+----+----+
|  0|勇士|  胜|    客|  10|    23|     0.435|              0.444|   6|  11|  27|
|  1|国王|  胜|    客|   8|    21|     0.381|0.28600000000000003|   3|   9|  27|
|  2|小牛|  胜|    主|  10|    19|     0.526|              0.462|   3|   7|  29|
+---+----+----+------+----+------+----------+-------------------+----+----+----+
only showing top 3 rows


from pyspark.sql.types import IntegerType, FloatType

df = df.withColumn('命中', df['命中'].cast(IntegerType()))
df = df.withColumn('投篮数', df['投篮数'].cast(IntegerType()))
df = df.withColumn('投篮命中率', df['投篮命中率'].cast(FloatType()))
df = df.withColumn('3分命中率', df['3分命中率'].cast(FloatType()))
df = df.withColumn('篮板', df['篮板'].cast(IntegerType()))
df = df.withColumn('助攻', df['助攻'].cast(IntegerType()))
df = df.withColumn('得分', df['得分'].cast(IntegerType()))

df.printSchema()
root
 |-- _c0: string (nullable = true)
 |-- 对手: string (nullable = true)
 |-- 胜负: string (nullable = true)
 |-- 主客场: string (nullable = true)
 |-- 命中: integer (nullable = true)
 |-- 投篮数: integer (nullable = true)
 |-- 投篮命中率: float (nullable = true)
 |-- 3分命中率: float (nullable = true)
 |-- 篮板: integer (nullable = true)
 |-- 助攻: integer (nullable = true)
 |-- 得分: integer (nullable = true)


alias

为列取个别名

df.select(df['对手'].alias('比赛对手')).show(3)
+--------+
|比赛对手|
+--------+
|    勇士|
|    国王|
|    小牛|
+--------+
only showing top 3 rows


asc

升序排列一个列

  • asc_nulls_first() 空值在前
  • asc_nulls_last() 空值在后
# 根据得分升序排列,并打印前5个对手和得分
df.select('对手', '得分').orderBy(df['得分'].asc()).show(5)
+------+----+
|  对手|得分|
+------+----+
|  灰熊|  20|
|  掘金|  21|
|  灰熊|  22|
|  鹈鹕|  26|
|步行者|  26|
+------+----+
only showing top 5 rows


astype()

转换数据类型,是cast的别名

between

一个布尔表达式,如果该表达式的值在给定列之间,则计算为true。可用于筛选满足条件的Row

# 筛选出得分在15-10之间数据(包含边界)
df1 = df.select('对手', df['得分'].between(15, 20).alias('selected_df'))
df1.filter(df1['selected_df'] == True).show()
+----+-----------+
|对手|selected_df|
+----+-----------+
|灰熊|       true|
+----+-----------+


bitwiseAND: 二进制与操作

bitwiseOR: 二进制或操作

bitwiseOR: 二进制异或操作

contains(other)

包含其他元素。 根据字符串匹配返回一个布尔列

df.filter(df['对手'].contains('小')).show()
+---+----+----+------+----+------+----------+---------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+---------+----+----+----+
|  2|小牛|  胜|    主|  10|    19|     0.526|    0.462|   3|   7|  29|
+---+----+----+------+----+------+----------+---------+----+----+----+


desc()

desc_nulls_first()

desc_nulls_last()

降序排列

df.select('对手', '得分').orderBy(df['得分'].desc()).show(5)
+------+----+
|  对手|得分|
+------+----+
|  爵士|  56|
|开拓者|  48|
|  太阳|  48|
|  猛龙|  38|
|  灰熊|  38|
+------+----+
only showing top 5 rows


endswith(other)

boolen值,以other结尾的字符串

df.filter(df['对手'].endswith('熊')).show()
+---+----+----+------+----+------+----------+---------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+---------+----+----+----+
|  3|灰熊|  负|    主|   8|    20|       0.4|     0.25|   5|   8|  22|
|  6|灰熊|  负|    客|   6|    19|     0.316|    0.222|   4|   8|  20|
| 12|灰熊|  胜|    主|  11|    25|      0.44|    0.429|   4|   8|  38|
| 16|灰熊|  胜|    客|   9|    20|      0.45|      0.5|   5|   7|  29|
+---+----+----+------+----+------+----------+---------+----+----+----+


eqNullSafe(other)

空值/指定值判断

from pyspark.sql import Row

df1 = spark.createDataFrame([Row(id=1, value='foo'), Row(id=2, value=None)])
df1.select('id', 'value', df1.value.eqNullSafe('foo'), df1.value.eqNullSafe(None)).show()
+---+-----+---------------+----------------+
| id|value|(value <=> foo)|(value <=> NULL)|
+---+-----+---------------+----------------+
|  1|  foo|           true|           false|
|  2| null|          false|            true|
+---+-----+---------------+----------------+


isNotNull()

当前表达式非空,返回True

df1.select('id', 'value', df1.value.isNotNull()).show()
+---+-----+-------------------+
| id|value|(value IS NOT NULL)|
+---+-----+-------------------+
|  1|  foo|               true|
|  2| null|              false|
+---+-----+-------------------+


isNull()

当前表达式为空,返回True

df1.select('id', 'value', df1.value.isNull()).show()
+---+-----+---------------+
| id|value|(value IS NULL)|
+---+-----+---------------+
|  1|  foo|          false|
|  2| null|           true|
+---+-----+---------------+


isin()

一个布尔表达式,如果自变量的求值包含该表达式的值,则该表达式为true。

# 取出对手为['灰熊', '76人', '骑士']的数据
df.filter(df['对手'].isin(['灰熊', '76人', '骑士'])).show()
+---+----+----+------+----+------+----------+---------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+---------+----+----+----+
|  3|灰熊|  负|    主|   8|    20|       0.4|     0.25|   5|   8|  22|
|  4|76人|  胜|    客|  10|    20|       0.5|     0.25|   3|  13|  27|
|  6|灰熊|  负|    客|   6|    19|     0.316|    0.222|   4|   8|  20|
|  7|76人|  负|    主|   8|    21|     0.381|    0.429|   4|   7|  29|
| 11|骑士|  胜|    主|   8|    21|     0.381|    0.429|  11|  13|  35|
| 12|灰熊|  胜|    主|  11|    25|      0.44|    0.429|   4|   8|  38|
| 16|灰熊|  胜|    客|   9|    20|      0.45|      0.5|   5|   7|  29|
+---+----+----+------+----+------+----------+---------+----+----+----+


like(other)

类似于SQL中的like, 返回基于SQL LIKE匹配的布尔列。

# 返回以‘灰’开头的
df.select('对手', '胜负', '主客场', '得分').where(df['对手'].like('灰%')).show()
+----+----+------+----+
|对手|胜负|主客场|得分|
+----+----+------+----+
|灰熊|  负|    主|  22|
|灰熊|  负|    客|  20|
|灰熊|  胜|    主|  38|
|灰熊|  胜|    客|  29|
+----+----+------+----+


otherwise(value)

计算条件列表,并返回多个可能的结果表达式之一。

# 增加标志列flag,将灰熊标志为1,其他对手标志为0
from pyspark.sql import functions as F
df.withColumn('flag', F.when(df['对手'] == '灰熊', 1).otherwise(0)).show(5)
+---+----+----+------+----+------+----------+---------+----+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|3分命中率|篮板|助攻|得分|flag|
+---+----+----+------+----+------+----------+---------+----+----+----+----+
|  0|勇士|  胜|    客|  10|    23|     0.435|    0.444|   6|  11|  27|   0|
|  1|国王|  胜|    客|   8|    21|     0.381|    0.286|   3|   9|  27|   0|
|  2|小牛|  胜|    主|  10|    19|     0.526|    0.462|   3|   7|  29|   0|
|  3|灰熊|  负|    主|   8|    20|       0.4|     0.25|   5|   8|  22|   1|
|  4|76人|  胜|    客|  10|    20|       0.5|     0.25|   3|  13|  27|   0|
+---+----+----+------+----+------+----------+---------+----+----+----+----+
only showing top 5 rows


rlike(other)

SQL RLIKE表达式(与Regex相似)。 根据正则表达式匹配返回布尔列。

df.filter(df['对手'].rlike('熊$')).show()
+---+----+----+------+----+------+----------+---------+----+----+----+
|_c0|对手|胜负|主客场|命中|投篮数|投篮命中率|3分命中率|篮板|助攻|得分|
+---+----+----+------+----+------+----------+---------+----+----+----+
|  3|灰熊|  负|    主|   8|    20|       0.4|     0.25|   5|   8|  22|
|  6|灰熊|  负|    客|   6|    19|     0.316|    0.222|   4|   8|  20|
| 12|灰熊|  胜|    主|  11|    25|      0.44|    0.429|   4|   8|  38|
| 16|灰熊|  胜|    客|   9|    20|      0.45|      0.5|   5|   7|  29|
+---+----+----+------+----+------+----------+---------+----+----+----+


startswith(other)

返回一个boolen列,以other开始的返回为True

df.select('对手', df['对手'].startswith('灰').alias('灰%')).show(5)
+----+-----+
|对手|  灰%|
+----+-----+
|勇士|false|
|国王|false|
|小牛|false|
|灰熊| true|
|76人|false|
+----+-----+
only showing top 5 rows


substr(startPos, length)

返回一个Column,它是该列的子字符串。

# 返回对手名称的第一个字符, 并命名为‘子串’
df.select('对手', df['对手'].substr(1, 1).alias('子串')).show(3)
+----+----+
|对手|子串|
+----+----+
|勇士|  勇|
|国王|  国|
|小牛|  小|
+----+----+
only showing top 3 rows


when(condition, value)

计算条件列表,并返回多个可能的结果表达式之一。 如果未调用Column.otherwise(),则对于不匹配的条件,将不返回None。

# 查找得分大于25的对手,标记为1,否则标记为0,标记列名为‘score_flag’
from pyspark.sql import functions as F

df.select('对手','得分', F.when(df['得分'] > 25, 1).otherwise(0).alias('score_flag')).show(5)
+----+----+----------+
|对手|得分|score_flag|
+----+----+----------+
|勇士|  27|         1|
|国王|  27|         1|
|小牛|  29|         1|
|灰熊|  22|         0|
|76人|  27|         1|
+----+----+----------+
only showing top 5 rows


getItem(key)

该表达式从列表中的第一个位置获取项目,或从字典中通过键获取一个项目

df1 = spark.createDataFrame([([1, 2], {'key': 'value'})], ['l', 'd'])
df1.select(df1.l.getItem(0), df1.d.getItem('key')).show()
+----+------+
|l[0]|d[key]|
+----+------+
|   1| value|
+----+------+

文末致敬官方文档:http://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.Column