DataFrame列名称与。(点)冲突

时间:2018-02-28 14:55:59

标签: scala apache-spark apache-spark-sql

我有一个DataFrame df,它有这个架构:

root
 |-- person.name: string (nullable = true)
 |-- person: struct (nullable = true)
 |    |-- age: long (nullable = true)
 |    |-- name: string (nullable = true)

当我df.select("person.name")时,我显然会从name获取子字段person。如何选择列person.name

3 个答案:

答案 0 :(得分:8)

对于包含.(dot)的列名,您可以使用`字符括起列名

df.select("`person.name`") 

这将选择外部字符串person.name: string (nullable = true)

df.select("person.name")

这将获取结构

的人名
 |-- person: struct (nullable = true)
 |    |-- age: long (nullable = true)

如果你有一个列名,你可以在列名前加上`字符作为

"`" + columnName + "`"

我希望这有用!

答案 1 :(得分:1)

我的答案提供了一个工作代码段,该代码段说明了列名称中包含点的问题,并说明了如何轻松地从列名称中删除点。

让我们使用一些示例数据创建一个DataFrame:

schema = StructType([
    StructField("person.name", StringType(), True),
    StructField("person", StructType([
        StructField("name", StringType(), True),
        StructField("age", IntegerType(), True)]))
])
data = [
    ("charles", Row("chuck", 42)),
    ("larry", Row("chipper", 48))
]
df = spark.createDataFrame(data, schema)
df.show()
+-----------+-------------+
|person.name|       person|
+-----------+-------------+
|    charles|  [chuck, 42]|
|      larry|[chipper, 48]|
+-----------+-------------+

让我们说明,根据是否使用反引号,选择person.name将返回不同的结果。

cols = ["person.name", "person", "person.name", "`person.name`"]
df.select(cols).show()
+-----+-----------+-----+-----------+
| name|     person| name|person.name|
+-----+-----------+-----+-----------+
|chuck|[chuck, 42]|chuck|    charles|
|larry|[larry, 73]|larry|   lawrence|
+-----+-----------+-----+-----------+

您绝对不希望编写或维护会因反引号而更改结果的代码。开始分析时,最好用下划线替换所有点。

clean_df = df.toDF(*(c.replace('.', '_') for c in df.columns))
clean_df.select("person_name", "person.name", "person.age").show()
+-----------+-----+---+
|person_name| name|age|
+-----------+-----+---+
|    charles|chuck| 42|
|   lawrence|larry| 73|
+-----------+-----+---+

This post详细解释了如何以及为什么要避免在PySpark列名称中出现圆点。

答案 2 :(得分:0)

要使用pyspark使用句点访问name列,请执行以下操作:

spark.sql("select person.name from person_table")

注意: person_table是df上的registerTempTable。