我在一个pyspark数据帧中有一个数组列,我想要找到每个数组中第一个正数的索引.数据如下所示:

id arr
Cell 1 -1, -1, -1, -1
Cell 2 -1, -1, 5, -1
Cell 3 -1, 3, -1, -1

我希望得到类似于以下内容的输出:

id arr first_positive_element_index
Cell 1 -1, -1, -1, -1 null
Cell 2 -1, -1, 5, -1 2
Cell 3 -1, 3, -1, -1 1

我可以使用UDF来做到这一点,但数据非常大,这使得这种方法非常慢.如果有更好的方法绕过这个问题,而不使用UDF,我会更喜欢.

注:所有非正数均为-1

推荐答案

您可以使用带有array_positionexpr:

df_pos = df.select(
    'id', 'arr',
    func.explode('arr').alias('arr_explode_value')
).filter(
    func.col('arr_explode_value')>=0
).withColumn(
    'pos', func.expr('array_position(arr, arr_explode_value)')-1
).groupBy(
    'id'
).agg(
    func.min('pos').alias('pos')
)
df_pos.show(10, False)
+------+---+
|id    |pos|
+------+---+
|Cell 2|2  |
|Cell 3|1  |
+------+---+

您可以创建数据帧以

  1. 分解数组
  2. 过滤掉正值
  3. 找到最小的索引

其余部分是将引用表连接回数据帧.

df.select('id', 'arr').join(df_pos.select('id', 'pos'), on=['id'], how='left')

编辑1:

如果因为长数组而不想使用explode,则可以使用transformarray_position:

df.select(
    'id', 'arr',
    func.transform(func.col('arr'), lambda value: func.when(value>=0, 1).otherwise(0)).alias('transformed_arr')
).withColumn(
    'pos', func.array_position('transformed_arr', 1)-1
).show(
    10, False
)
+------+----------------+---------------+---+
|id    |arr             |transformed_arr|pos|
+------+----------------+---------------+---+
|Cell 1|[-1, -1, -1, -1]|[0, 0, 0, 0]   |-1 |
|Cell 2|[-1, -1, 5, -1] |[0, 0, 1, 0]   |2  |
|Cell 3|[-1, 3, -1, -1] |[0, 1, 0, 0]   |1  |
+------+----------------+---------------+---+

由于第arr列是数组类型,因此可以使用transform对元素应用函数.

Python相关问答推荐

沿着数组中的轴计算真实条目

使用@ guardlasses. guardlass和注释的Python继承

当独立的网络调用不应该互相阻塞时,'

如何获得每个组的时间戳差异?

如果值发生变化,则列上的极性累积和

SQLAlchemy Like ALL ORM analog

使用groupby方法移除公共子字符串

如何指定列数据类型

为什么\b在这个正则表达式中不解释为反斜杠

Python—转换日期:价目表到新行

搜索按钮不工作,Python tkinter

Pandas:填充行并删除重复项,但保留不同的值

为什么在FastAPI中创建与数据库的连接时需要使用生成器?

从源代码显示不同的输出(机器学习)(Python)

简单 torch 模型测试:ModuleNotFoundError:没有名为';Ultralytics.yolo';

如何在Django模板中显示串行化器错误

两个名称相同但值不同的 Select 都会产生相同的值(discord.py)

我如何为测试函数的参数化提供fixture 生成的数据?如果我可以的话,还有其他 Select 吗?

将标签与山脊线图对齐

如何批量训练样本大小为奇数的神经网络?