PySpark Row对象:按变量名访问行元素

时间:2016-03-23 08:02:13

标签: python apache-spark pyspark

可以使用点表示法访问PySpark Row元素:给定r= Row(name="Alice", age=11),可以分别使用r.namer.age获取名称或年龄。当需要获取名称存储在变量element中的元素时会发生什么?一种选择是r.toDict()[element]。但是,考虑一下我们有一个大DataFrame的情况,我们希望在该数据帧的每一行上映射一个函数。我们当然可以做像

这样的事情
def f(row, element1, element2):
    row = row.asDict()
    return ", ".join(str(row[element1]), str(row[element2]))

result = dataframe.map(lambda row: f(row, 'age', 'name'))

但是,似乎每行调用toDict()效率非常低。还有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

如果一切正常,那么就像在Python中一样,那里没有任何魔力。当某些东西起作用时,就像这里的点语法一样,它意味着可预测的事件链。特别是您可以期望调用__getattr__方法:

from pyspark.sql import Row

a_row = Row(foo=1, bar=True)

a_row.__getattr__("foo")
## 1
a_row.__getattr__("bar")
True

行也会覆盖__getitem__以使其具有相同的行为:

a_row.__getitem__("foo")
## 1

这意味着您可以使用括号表示法:

a_row["bar"]
## True

问题是效率不高。每次调用都是 O(N),因此如果您有大行和多次调用,则单次转换为dict会更有效。

一般来说,你应该避免这样的电话:

  • 使用UDF效率低但通常更清洁
  • 使用内置SQL表达式应优先于map
  • 您不应直接在DataFrame上映射。它很快就会被弃用。

答案 1 :(得分:0)

python_var_list =[ [ele[0],ele[1]] for ele in r]

上面的代码行应为r中的每一行访问pyspark中的行元素