【问题标题】:SparkSQL query dataframeSparkSQL 查询数据框
【发布时间】:2020-01-29 08:00:34
【问题描述】:

我将 pandas 数据框转换为 spark sql 表。我是 SQL 新手,想从表中选择键“代码”。

查询

sqlContext.sql("""SELECT `classification` FROM psyc""").show()

查询响应

+--------------------+
|      classification|
+--------------------+
|[{'code': '3297',...|
|[{'code': '3410',...|
|[{'code': '3410',...|
|[{'code': '2227',...|
|[{'code': '3410',...|
+--------------------+

如何选择关键的“代码”。该列包含一个包含数据的 dict 列表。

 sqlContext.sql("""SELECT `classification.code` FROM psyc""").show() # this query does not work

这是剩下的代码

from pyspark.sql import SparkSession
from pyspark.sql import SQLContext

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL ") \
    .getOrCreate()

sc = spark.sparkContext                       
sqlContext = SQLContext(sc)

fp = os.path.join(BASE_DIR,'psyc.csv')
df = spark.read.csv(fp,header=True)
df.printSchema()
df.createOrReplaceTempView("psyc")

这将创建一个具有以下架构的表

【问题讨论】:

    标签: sql python-3.x pyspark apache-spark-sql pyspark-sql


    【解决方案1】:

    classification字段是string类型的,所以先把它转换成struct类型,然后直接选择classification.code。要将字符串转换为结构,请尝试以下操作。

    //Sample Dataframe
    from pyspark.sql.types import *
    df=spark.createDataFrame([(1,"[{'code':'1234','name':'manoj'},{'code':'124','name':'kumar'},{'code':'4567','name':'dhakad'}]",),(2,"[{'code':'97248','name':'joe'},{'code':'2424','name':'alice'},{'code':'464','name':'bob'}]",)],["id","classification",])
    
    //df will be below
    +---+--------------------+
    | id|      classification|
    +---+--------------------+
    |  1|[{'code':'1234','...|
    |  2|[{'code':'97248',...|
    +---+--------------------+
    
    //here is schema of above df
    root
        |-- id: long (nullable = true)
        |-- classification: string (nullable = true) 
    
    
    //df after converting classification column to the struct type and selecting only code.
    
    schema = ArrayType(StructType([StructField('code', StringType()), StructField('name', StringType())]))
    df1=df.withColumn('classification',from_json(col("classification"),schema=schema))
    
    df2=df1.withColumn("code",col("classification.code"))
    
    +---+--------------------+------------------+
    | id|      classification|              code|
    +---+--------------------+------------------+
    |  1|[[1234,manoj], [1...| [1234, 124, 4567]|
    |  2|[[97248,joe], [24...|[97248, 2424, 464]|
    +---+--------------------+------------------+
    
    //Here, I am going to select id and while exploding code column
    
    df3=df2.select(col("id"),explode(col("code")))
    df3.show()
    
    
    //df3 output
    +---+-----+
    | id|  col|
    +---+-----+
    |  1| 1234|
    |  1|  124|
    |  1| 4567|
    |  2|97248|
    |  2| 2424|
    |  2|  464|
    +---+-----+
    

    【讨论】:

    • 我怎样才能将键'code'的值作为int或string。目前,我得到一个具有字符串值的数组。
    • 使用分解函数:df1.withColumn("code",explode(col("classification.code")))
    • 它只返回第一个元素。如何确保返回列表中的所有元素
    • 嗨@joel,添加详细答案,请了解结构数据类型和分解功能。
    【解决方案2】:

    试试这个

    df.select(F.explode("classification").alias("classification")).select("classification.code").show()
    

    【讨论】:

      猜你喜欢
      • 2015-09-29
      • 2016-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多