在pyspark中,可以使用列对象和字符串来选择列。两种方法返回相同的结果。有什么区别吗?什么时候应该使用列对象而不是字符串?例如,我可以使用列对象:
import pyspark.sql.functions as F
df.select(F.lower(F.col('col_name')))
# or
df.select(F.lower(df['col_name']))
# or
df.select(F.lower(df.col_name))
或者我可以用一个字符串来代替,得到相同的结果:
df.select(F.lower('col_name'))
在pyspark中使用列对象而不是字符串有什么好处
2条答案
按热度按时间jaql4c8m1#
这取决于scala中函数的实现方式。在scala中,函数的签名是函数本身的一部分。例如,
func(foo: str)
以及func(bar: int)
是两个不同的函数,scala可以根据所使用的参数类型决定是否调用其中一个函数。F.col('col_name'))
,df['col_name']
以及df.col_name
是同一类型的对象,一列。使用一种或另一种语法几乎是一样的。有一点不同的是,你可以这样写:当你打电话的时候
df.select(F.lower('col_name'))
,如果函数lower(smth: str)
没有在scala中定义,那么您将有一个错误。有些函数是用str作为输入定义的,有些函数只接受columns对象。试着知道它是否有效,然后使用它。否则,您可以对spark项目发出pull请求以添加新签名。g6ll5ycj2#
阅读这个Pypark风格的指南从帕兰蒂尔在这里解释什么时候使用
F.col()
而不是最佳实践。git链接在这里在许多情况下,第一种风格可以更简单,更短,视觉污染更小。然而,我们发现它面临许多限制,这导致我们更喜欢第二种风格:
如果dataframe变量名很大,那么涉及它的表达式很快就会变得笨拙;如果列名包含空格或其他不支持的字符,则必须改用方括号运算符。这会产生不一致,并且
df1['colA']
写起来和写起来一样难F.col('colA')
; 涉及dataframe的列表达式是不可重用的,不能用于定义抽象函数;重命名dataframe变量很容易出错,因为所有列引用都必须同步更新。此外,dot语法鼓励对dataframes使用简短的非描述性变量名,我们发现这对可维护性有害。请记住,dataframes是数据的容器,描述性名称是快速设置对其中所包含内容的期望的有用方法。相比之下,
F.col('colA')
在本例中,将始终引用正在操作的Dataframe中指定为cola的列,名为df。它完全不需要跟踪其他Dataframe的状态,因此代码变得更局部,更不容易受到“远距离的可怕交互”的影响,这通常是调试的挑战。