当前位置: 首页 > 知识库问答 >
问题:

PySpark DataFrame列引用:DF.col vs.DF['col']vs.F.col('col')?

桑飞语
2023-03-14
    null

多谢!

共有1个答案

游皓
2023-03-14

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

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

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|
#+----+----+---------+

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

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
>>> df.2col
  File "<ipython-input-39-8e82c2dd5b7c>", line 1
    df.2col
       ^
SyntaxError: invalid syntax
df["2col"]
#Column<2col> 

此外,还可以在多个列(作为列表元组)或列表达式中传递。

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>
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|
#+----+----+---------+---------+
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|
#+----+----+---------+---+

因为是col()创建列表达式而不进行检查,所以有两个有趣的副作用。

  1. 它可以重用,因为它不是特定于df的
  2. 可在分配df之前使用
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'))

年龄生成
IF_expr生成

 类似资料:
  • 我现在正在阅读Twitter Bootstrap 3上的文档,并尝试按照本页所示的列顺序进行排序,但遇到了问题。我不明白为什么这样的代码可以工作,也不知道如何正确地指定设置。我想展示的是一个网格,它由长度5组成,另一个长度5,最后是一个长度2的网格。 所以我的是这样的: 我想实现的是,当它在桌面上查看时,上面的布局会显示出来,但是当它在移动设备上查看时,我想先显示第二个长度5的对象,然后是第一个长

  • 问题内容: 我现在正在阅读Twitter Bootstrap3上的文档,并试图按照此页面上所示的顺序进行排序,但遇到了麻烦。我不明白为什么这样的代码有效,也不知道如何正确指定设置。我要显示的是一个网格,它由长度5,另一个长度5和最后一个长度2网格组成。 所以我的是这样的: 我要实现的是,在桌面上查看时会显示上面的布局,但是在移动设备上查看时,我想先显示第二个长度为5的对象,然后是第一个长度为5的对

  • 问题内容: 是什么之间的差异,并在Twitter的引导? 问题答案: 2019年更新… 所述 自举3 格进来 4 层(或“断点”)… 特小(适用于智能手机) 小(用于平板电脑) 中(笔记本电脑用) 大(适用于笔记本电脑/台式机)。 这些网格大小使您可以控制不同宽度上的网格行为。不同的层由CSS 媒体查询控制。 因此,在Bootstrap的12列网格中… 在典型的 小型 设备宽度(> 768像素)上

  • 问题内容: 我有一个这样的表: 我现在想获取所有具有多个值的条目。预期结果将是: 我试图做到这一点是这样的: 但是甲骨文不喜欢它。 所以我尝试了这个 …没有成功。 有任何想法吗? 问题答案: 使用该子句比较聚合。 另外,您需要根据要汇总的内容进行分组,以使查询正常运行。以下是一个开始,但是由于您缺少group by子句,因此仍然无法正常工作。您到底想算什么?

  • 描述 (Description) HTML标记允许作者将表列的属性规范组合在一起。 它不会在结构上将列组合在一起 - 这是元素的作用。 元素为空,仅用作对属性的支持。 例子 (Example) <!DOCTYPE html> <html> <head> <title>HTML col Tag</title> </head> <body> <p>This e

  • 问题内容: 我对新的Bootstrap中的网格系统感到困惑,尤其是这些类: (其中*代表一些数字)。 任何人都可以解释以下内容: __这个数字 如何 对齐网格? 如何 使用这些数字? 什么 他们实际上代表什么呢? 问题答案: 仅适用于Bootstrap 3。 忽略字母(X 小号 , SM , MD , LG ) 现在 ,我只用数字开始… 数字(1-12)代表任何div总宽度的一部分 所有div分为