【问题标题】:Is there a function in spark df that can be replaced by applymap?spark df中是否有可以被applymap替换的函数?
【发布时间】:2020-05-31 10:49:48
【问题描述】:

以下是为 pandas df 编写的代码,由于内存问题,我不得不转移到 PySpark,这就是为什么我需要转换此代码以便可以为 spark df 执行它。我尝试直接运行它,但它会产生错误。PySpark 中以下代码的替代方法是什么?

def units(x):
    if x <= 0:
        return 0
    if x >= 1:
        return 1

sets = df.applymap(units)

这是我得到的错误:

AttributeErrorTraceback (most recent call last)
<ipython-input-20-7e54b4e7a7e7> in <module>()
----> 1 sets = pivoted.applymap(units)

/usr/lib/spark/python/pyspark/sql/dataframe.py in __getattr__(self, name)
   1180         if name not in self.columns:
   1181             raise AttributeError(
-> 1182                 "'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
   1183         jc = self._jdf.apply(name)
   1184         return Column(jc)

AttributeError: 'DataFrame' object has no attribute 'applymap'

【问题讨论】:

  • Pyspark 数据框没有 applymap 属性,看看 when+otherwise: df.select(*[F.when(F.col(i)&lt;=0,0).otherwise(1).alias(i) for i in df.columns]).show() ?将 sql 函数导入为 F 后,如 import pyspark.sql.functions as F

标签: python pandas apache-spark pyspark google-cloud-dataproc


【解决方案1】:

您可以将单位函数包装为 UDF:

from pyspark.sql.types import LongType
from pyspark.sql.functions import udf, col

def units(x):
    if x <= 0:
        return 0
    if x >= 1:
        return 1

units_udf = udf(lambda x: units(x), LongType())

df = spark.createDataFrame([(-1,), (0,), (1,), (2,)], ['id'])

df.show()
+---+                                                                           
| id|
+---+
| -1|
|  0|
|  1|
|  2|
+---+

sets = df.withColumn("id", units_udf(col("id")))
sets.show()
+---+
| id|
+---+
|  0|
|  0|
|  1|
|  1|
+---+

【讨论】:

  • 如果我想将 udf 应用于所有列,即整个数据框,该怎么办?
  • 我能想到的方法有两种。您可以将数据框的所有列转换为复杂类型(结构)的单个列,并将该列传递给 UDF。或者您可以将您的数据框转换为行的 rdd,在该 rdd 上调用地图(地图中的函数必须接受并返回 Row 类型),然后转换回数据框。
猜你喜欢
  • 1970-01-01
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
  • 2017-07-20
  • 1970-01-01
相关资源
最近更新 更多