【问题标题】:DataFrame columns names conflict with .(dot)DataFrame 列名称与 .(dot) 冲突
【发布时间】:2020-07-23 01:31:29
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    并且 df.select("person.name")

    这会得到人名,即结构

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

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

    "`" + columnName + "`"
    

    我希望这会有所帮助!

    【讨论】:

    • 当我的列名实际上是字符串变量时怎么办?
    • 你能看看这个吗?谢谢! stackoverflow.com/questions/48986102/…
    • 我不确定 wat 是否正确,但它就像“" + columnName + "”一样工作
    • 是的,谢谢!试试这个: df.select(" ` " + col_name + " ` ").show()
    【解决方案2】:

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

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

    注意: person_table 是 df 上的 registerTempTable。

    【讨论】:

      【解决方案3】:

      我的回答提供了一个工作代码 sn-p,它说明了列名中包含点的问题,并解释了如何轻松地从列名中删除点。

      让我们用一些示例数据创建一个 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 列名称中的点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 1970-01-01
        • 2017-10-31
        • 2023-02-10
        • 2020-06-18
        • 2011-11-25
        • 1970-01-01
        相关资源
        最近更新 更多