PySpark DataFrame列参考:df.col与df ['col']与F.col('col')?

Zil*_*g Z 4 reference dataframe pyspark

我有一个概念,希望您能帮助澄清:

引用PySpark数据框中的列的以下三种方式之间有什么区别?我知道不同的情况需要不同的形式,但不确定为什么。

  1. df.col:例如 F.count(df.col)
  2. df ['col']:例如 df['col'] == 0
  3. F.col('col'):例如 df.filter(F.col('col').isNull())

非常感谢!

pau*_*ult 5

在大多数实际应用中,几乎没有区别。但是,它们是通过调用不同的基础函数(source)来实现的,因此并不完全相同

我们可以举一个小例子来说明:

df = spark.createDataFrame(
    [(1,'a', 0), (2,'b',None), (None,'c',3)], 
    ['col', '2col', 'third col']
)

df.show()
#+----+----+---------+
#| col|2col|third col|
#+----+----+---------+
#|   1|   a|        0|
#|   2|   b|     null|
#|null|   c|        3|
#+----+----+---------+
Run Code Online (Sandbox Code Playgroud)

1。 df.col

这是最不灵活的。您只能引用可使用.运算符访问的有效列。这排除了包含空格或特殊字符的列名称以及以整数开头的列名称。

该语法调用df.__getattr__("col")

print(df.__getattr__.__doc__)
#Returns the :class:`Column` denoted by ``name``.
#
#        >>> df.select(df.age).collect()
#        [Row(age=2), Row(age=5)]
#
#        .. versionadded:: 1.3
Run Code Online (Sandbox Code Playgroud)

使用.语法,您只能访问此示例数据框的第一列。

>>> df.2col
  File "<ipython-input-39-8e82c2dd5b7c>", line 1
    df.2col
       ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

在后台,它检查是否包含列名df.columns,然后返回pyspark.sql.Column指定的名称。

2。 df["col"]

这会呼叫df.__getitem__。您具有更大的灵活性,因为您可以做所有__getattr__可以做的事情,还可以指定任何列名。

df["2col"]
#Column<2col> 
Run Code Online (Sandbox Code Playgroud)

再次在后台检查一些条件,在这种情况下pyspark.sql.Column,将返回输入字符串指定的条件。

此外,您可以传入多个列(如a listtuple)或列表达式。

from pyspark.sql.functions import expr
df[['col', expr('`third col` IS NULL')]].show()
#+----+-------------------+
#| col|(third col IS NULL)|
#+----+-------------------+
#|   1|              false|
#|   2|               true|
#|null|              false|
#+----+-------------------+
Run Code Online (Sandbox Code Playgroud)

请注意,在多列的情况下,__getitem__只需调用pyspark.sql.DataFrame.select

最后,您还可以按索引访问列:

df[2]
#Column<third col>
Run Code Online (Sandbox Code Playgroud)

3。 pyspark.sql.functions.col

这将Column基于给定名称返回一个。当您需要指定需要列而不是字符串文字时,这是有用的速记。

例如,假设我们想创建一个新列,该列采用来自"col""third col"基于的值"2col"

from pyspark.sql.functions import when

df.withColumn(
    'new', 
    f.when(df['2col'].isin(['a', 'c']), 'third col').otherwise('col')
).show()
#+----+----+---------+---------+
#| col|2col|third col|      new|
#+----+----+---------+---------+
#|   1|   a|        0|third col|
#|   2|   b|     null|      col|
#|null|   c|        3|third col|
#+----+----+---------+---------+
Run Code Online (Sandbox Code Playgroud)

糟糕,这不是我的意思。Spark认为我需要文字字符串"col""third col"。相反,我应该写的是:

from pyspark.sql.functions import col
df.withColumn(
    'new', 
    when(df['2col'].isin(['a', 'c']), col('third col')).otherwise(col('col'))
).show()
#+----+----+---------+---+
#| col|2col|third col|new|
#+----+----+---------+---+
#|   1|   a|        0|  0|
#|   2|   b|     null|  2|
#|null|   c|        3|  3|
#+----+----+---------+---+
Run Code Online (Sandbox Code Playgroud)