当前位置: 首页 > 面试题库 >

如何在Spark SQL中压缩两个数组列

太叔望
2023-03-14
问题内容

我有一个熊猫数据框。我尝试将包含字符串值的两列首先连接到列表中,然后使用zip,我将列表的每个元素都用’_’连接。我的数据集如下:

df['column_1']: 'abc, def, ghi'
df['column_2']: '1.0, 2.0, 3.0'

我想将这两列连接到第三列,如下所示,分别用于数据框的每一行。

df['column_3']: [abc_1.0, def_2.0, ghi_3.0]

我已经使用下面的代码在python中成功完成了此操作,但该数据框非常大,并且需要花费很长时间才能为整个数据框运行它。我想在PySpark中做同样的事情以提高效率。我已经成功读取了spark数据框中的数据,但是我很难确定如何使用PySpark等效函数复制Pandas函数。如何在PySpark中获得想要的结果?

df['column_3'] = df['column_2']
for index, row in df.iterrows():
  while index < 3:
    if isinstance(row['column_1'], str):      
      row['column_1'] = list(row['column_1'].split(','))
      row['column_2'] = list(row['column_2'].split(','))
      row['column_3'] = ['_'.join(map(str, i)) for i in zip(list(row['column_1']), list(row['column_2']))]

我已使用以下代码将两列转换为PySpark中的数组

from pyspark.sql.types import ArrayType, IntegerType, StringType
from pyspark.sql.functions import col, split

crash.withColumn("column_1",
    split(col("column_1"), ",\s*").cast(ArrayType(StringType())).alias("column_1")
)
crash.withColumn("column_2",
    split(col("column_2"), ",\s*").cast(ArrayType(StringType())).alias("column_2")
)

现在,我需要使用’_’在两列中压缩数组的每个元素。如何与此一起使用zip?任何帮助表示赞赏。


问题答案:

与Python等效的Spark
SQL为pyspark.sql.functions.arrays_zip

pyspark.sql.functions.arrays_zip(*cols)

集合函数:返回结构的合并数组,其中第N个结构包含输入数组的所有第N个值。

因此,如果您已经有两个数组:

from pyspark.sql.functions import split

df = (spark
    .createDataFrame([('abc, def, ghi', '1.0, 2.0, 3.0')])
    .toDF("column_1", "column_2")
    .withColumn("column_1", split("column_1", "\s*,\s*"))
    .withColumn("column_2", split("column_2", "\s*,\s*")))

您可以将其应用于结果

from pyspark.sql.functions import arrays_zip

df_zipped = df.withColumn(
  "zipped", arrays_zip("column_1", "column_2")
)

df_zipped.select("zipped").show(truncate=False)



+------------------------------------+
|zipped                              |
+------------------------------------+
|[[abc, 1.0], [def, 2.0], [ghi, 3.0]]|
+------------------------------------+

我们可以将结果合并transform(?如何使用变换高阶函数,类型错误:列不是可迭代-
如何遍历数组类型()? :

df_zipped_concat = df_zipped.withColumn(
    "zipped_concat",
     expr("transform(zipped, x -> concat_ws('_', x.column_1, x.column_2))")
)

df_zipped_concat.select("zipped_concat").show(truncate=False)



+---------------------------+
|zipped_concat              |
+---------------------------+
|[abc_1.0, def_2.0, ghi_3.0]|
+---------------------------+

注意事项

高阶功能transform,并arrays_zip已在Apache中星火2.4引入。



 类似资料:
  • 问题内容: 我有2个数组: 我想要得到的结果是: 看起来很简单,但我不知道。 我希望结果是一个数组,其中两个数组中的每个元素都压缩在一起。 问题答案: 使用方法:

  • 问题内容: 例如我有2个数组 我怎么能 和这样我得到 ? 问题答案: 您可以使用dstack: 如果必须有元组: 对于Python 3+,您需要扩展iterator对象。请注意,这是非常低效的:

  • 问题内容: 我有两个列表,每个列表具有相等数量的项目。这两个列表如下所示: 我正在寻找一个看起来像这样的清单: 我试图使用这样的东西: 合并两个列表列表的最佳方法是什么?提前致谢。 问题答案:

  • 问题内容: 我的应用程序正在通过SMTP服务器接收电子邮件。电子邮件中有一个或多个附件,电子邮件附件以byte []的形式返回(使用sun javamail api)。 我正在尝试快速压缩附件文件,而不先将其写入磁盘。 有什么/可能的方法来实现这一结果? 问题答案: 您可以使用Java的java.util.zip.ZipOutputStream在内存中创建一个zip文件。例如:

  • 问题内容: 使用Google Guava(Google Commons),是否可以将两个大小相等的列表合并为一个列表,而新列表包含两个输入列表的复合对象? 例: 和 将输出: 问题答案: 从Guava 21开始,可以通过以下方式实现: