我有一个概念,我希望你能帮助澄清:
以下三种引用PySpark数据格式中列的方法有什么区别。我知道不同的情况需要不同的形式,但不知道为什么。
F.count(df.col)df['col'] == 0df.filter(F.col('col').isNull()) )非常感谢!
发布于 2019-03-11 16:37:34
在大多数实际应用中,几乎没有区别。但是,它们是通过调用不同的底层函数(来源)来实现的,因此它们并不完全相同。
我们可以用一个小例子来说明:
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|
#+----+----+---------+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使用.语法,只能访问本示例的第一列dataframe。
>>> df.2col
  File "<ipython-input-39-8e82c2dd5b7c>", line 1
    df.2col
       ^
SyntaxError: invalid syntax在遮罩下,它检查列名是否包含在df.columns中,然后返回指定的pyspark.sql.Column。
2. df["col"]
这给df.__getitem__打了个电话。您有一些更大的灵活性,因为您可以完成__getattr__所能做的所有事情,并且可以指定任何列名。
df["2col"]
#Column<2col> 再次,在掩码下检查一些条件,在本例中,返回输入字符串指定的pyspark.sql.Column。
此外,还可以传入多个列(作为list或tuple)或列表达式。
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|
#+----+-------------------+注意,在多列的情况下,__getitem__只是在调用pyspark.sql.DataFrame.select。
最后,还可以按索引访问列:
df[2]
#Column<third col>3. pyspark.sql.functions.col
这是选择列的本机方式,并返回一个expression (所有列函数都是这样),它根据给定的名称选择列。当您需要指定一个列而不是字符串文本时,这是非常有用的速记。
例如,假设我们想要创建一个新列,它将根据"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|
#+----+----+---------+---------+噢,我不是这个意思。斯帕克认为我想要文字字符串"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|
#+----+----+---------+---+因为is col()在不检查的情况下创建列表达式,因此有两个有趣的副作用。
age = col('dob') / 365
if_expr = when(age < 18, 'underage').otherwise('adult')
df1 = df.read.csv(path).withColumn('age_category', if_expr)
df2 = df.read.parquet(path)\
    .select('*', age.alias('age'), if_expr.alias('age_category'))age生成Column<b'(dob / 365)'>
if_expr生成Column<b'CASE WHEN ((dob / 365) < 18) THEN underage ELSE adult END'>
https://stackoverflow.com/questions/55105363
复制相似问题