如何创建含带点(.)列名的Spark DataFrame?
解决Spark DataFrame含“.”列名的创建与操作问题
我之前也踩过这个坑!问题出在你定义Schema的方式上——你把反引号当成了列名的一部分,而实际上反引号只是Spark用来识别特殊列名(比如含.、空格或关键字的列)的引用符号,不是列名本身。
错误原因分析
你写的StructField("US.sales", FloatType(), True)会把列名实际设置为带反引号的字符串(也就是\US.sales`),而不是你想要的US.sales。这会导致Spark在执行count()`这类操作时,内部解析列名出现混乱,因为它会把这个带反引号的名称当成特殊结构处理。
正确的解决步骤
1. 正确定义Schema
创建StructField时,直接使用原始列名字符串"US.sales",不需要加反引号:
from pyspark.sql.types import StructType, StructField, StringType, FloatType # 模拟输入数据 input_data = [('retail', '2017-01-03T13:21:00', 134), ('retail', '2017-01-03T13:21:00', 100)] # 正确定义Schema:列名直接写"US.sales" rdd_schema = StructType([ StructField('business', StringType(), True), StructField('date', StringType(), True), StructField("US.sales", FloatType(), True) ]) # 创建DataFrame(注意你之前的代码里用了input_mock_rdd_map,这里直接传input_data即可,Spark会自动处理) input_mock_df = spark.createDataFrame(input_data, rdd_schema)
2. 验证与操作
现在执行count()就不会报错了:
# 查看列名,会输出['business', 'date', 'US.sales'] print(input_mock_df.columns) # 执行count操作,正常返回结果 print(input_mock_df.count())
3. 正确引用带“.”的列
后续操作中,当需要引用这个列时,有几种方式:
- DataFrame API方式:用反引号包裹列名,或者直接用字符串索引:
# 方式1:反引号引用 input_mock_df.select(`US.sales`).show() # 方式2:字符串直接引用 input_mock_df.select("US.sales").show() # 方式3:列对象引用 input_mock_df.select(input_mock_df["US.sales"]).show() - SQL查询方式:注册临时视图后,用反引号引用列名:
input_mock_df.createOrReplaceTempView("sales_view") spark.sql("SELECT `US.sales` FROM sales_view").show()
核心就是:列名本身是US.sales,反引号只是在引用时用来告诉Spark不要把.解析成嵌套结构的分隔符,不要把反引号写到Schema的列名定义里。
内容的提问来源于stack exchange,提问作者GeorgeOfTheRF




