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

Chr*_*ris 5 python struct apache-spark apache-spark-sql pyspark

下面的数据框是一个名为:“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)
Run Code Online (Sandbox Code Playgroud)

下面的查询

spark.sql("select MAIN_COL.* from table_name")
Run Code Online (Sandbox Code Playgroud)

返回名为 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"))
Run Code Online (Sandbox Code Playgroud)

Vap*_*ira 2

Spark 之美,您可以以编程方式操作元数据

这是一个延续原始代码片段的示例:

main.createOrReplaceTempView("table_name")

new_cols_select = ", ".join(["MAIN_COL." + col + " as pre_" + col for col in spark.sql("select MAIN_COL.* from table_name").columns])

new_df = spark.sql(f"select {new_cols_select} from table_name")
Run Code Online (Sandbox Code Playgroud)

由于 Spark 的惰性,并且所有操作都只是元数据,因此该代码几乎没有任何性能成本,并且对于 10 列或 500 列同样有效(我们实际上是在 1k 列上执行类似的操作)。

还可以使用df.schema对象以更优雅的方式获取原始列名称