python - 使用 'struct_name.*' 选择时为所有列提供前缀

标签 python pyspark apache-spark-sql pyspark-sql

下面的数据框是一个名为的 temp_table: 'table_name' 。
您将如何使用 spark.sql() 为所有列提供前缀?

root
 |-- MAIN_COL: struct (nullable = true)
 |    |-- a: string (nullable = true)
 |    |-- b: string (nullable = true)
 |    |-- c: string (nullable = true)
 |    |-- d: string (nullable = true)
 |    |-- f: long (nullable = true)
 |    |-- g: long (nullable = true)
 |    |-- h: long (nullable = true)
 |    |-- j: long (nullable = true)

下面的查询
spark.sql("select MAIN_COL.* from table_name")

返回名为 a,b,c... 的列,但是如何使它们看起来都像例如pre_a、pre_b、pre_c?
想要避免一一选择和给它们别名。如果我有 30 列怎么办?

我希望自定义 UDF 可以解决它在 SQL 中使用的问题,但真的不知道如何处理。
 # Generate a pandas DataFrame
import pandas as pd
a_dict={
    'a':[1,2,3,4,5],
    'b':[1,2,3,4,5],
    'c':[1,2,3,4,5],
    'e':list('abcde'),
    'f':list('abcde'),
    'g':list('abcde')
}
pandas_df=pd.DataFrame(a_dict)
# Create a Spark DataFrame from a pandas DataFrame using Arrow
spark.conf.set("spark.sql.execution.arrow.enabled", "true")
df = spark.createDataFrame(pandas_df)

#struct
from pyspark.sql.functions import struct
main=df.select(struct(df.columns).alias("MAIN_COL"))

最佳答案

这是一种遍历字段并动态修改其名称的方法。第一次使用 main.schema.fields[0].dataType.fields访问目标字段。接下来使用python map前置 pre_到每个字段:

from pyspark.sql.types import *
from pyspark.sql.functions import col

inner_fields = main.schema.fields[0].dataType.fields

# [StructField(a,LongType,true),
#  StructField(b,LongType,true),
#  StructField(c,LongType,true),
#  StructField(e,StringType,true),
#  StructField(f,StringType,true),
#  StructField(g,StringType,true)]

pre_cols = list(map(lambda sf: StructField(f"pre_{sf.name}", sf.dataType, sf.nullable), inner_fields))

new_schema = StructType(pre_cols)

main.select(col("MAIN_COL").cast(new_schema)).printSchema()

# root
#  |-- MAIN_COL: struct (nullable = false)
#  |    |-- pre_a: long (nullable = true)
#  |    |-- pre_b: long (nullable = true)
#  |    |-- pre_c: long (nullable = true)
#  |    |-- pre_e: string (nullable = true)
#  |    |-- pre_f: string (nullable = true)
#  |    |-- pre_g: string (nullable = true)

最后,您可以使用 cast使用@Mahesh 已经提到的新模式。

关于python - 使用 'struct_name.*' 选择时为所有列提供前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59960236/

相关文章:

python - "ImportError: cannot import name CaptchaFields "- Django

python - Matplotlib 设置 x 轴上的频率

python - pyspark MLUtils saveaslibsvm 仅保存在 _temporary 下,而不保存在 master 上

python - ###运行时错误: Java gateway process exited before sending its port number

sql - SPARK : failure: `` union '' expected but ` (' found

python - 如何索引多个值来代替单个值,但保持形状就像它是单个值一样?

python - scipy.integrate.odeint 是否可以输出内部计算

apache-spark - 如何计算 PySpark 数据帧中每个键的百分位数?

mysql - 基于另一个表 PySpark/SQL 的日期时间列聚合列

apache-spark - 在 Spark SQL 中插入如果不存在 ELSE 更新