提取价值从一个数组,总结到一定的价值pyspark

0

的问题

我有一个数据框有一系列与作为价值观。 内阵列,1或一笔数目等于一个特定的目标值,我要提取的数值,无论是平等的价值或可以被总结为平等的价值。 我想能够做到这一点,在PySpark.

| Array                  | Target    | NewArray         |
| -----------------------|-----------|------------------|
| [0.0001,2.5,3.0,0.0031]| 0.0032    | [0.0001,0.0031]  |
| [2.5,1.0,0.5,3.0]      | 3.0       | [2.5, 0.5, 3.0]  |
| [1.0,1.0,1.5,1.0]      | 4.5       | [1.0,1.0,1.5,1.0]|
arrays extract pyspark sum
2021-11-23 19:39:03
1

最好的答案

1

你可以封装的逻辑作为一个 udf 并创建 NewArray 在此基础上。 我已经借用了逻辑,用于识别要素的阵总结到一个目标值是从 这里.


from pyspark.sql.types import ArrayType, DoubleType
from pyspark.sql.functions import udf
from decimal import Decimal

data = [([0.0001,2.5,3.0,0.0031], 0.0032),
([2.5, 1.0, 0.5, 3.0], 3.0),
([1.0, 1.0, 1.5, 1.0], 4.5), 
([], 1.0),
(None, 1.0),
([1.0,2.0], None),]


df = spark.createDataFrame(data, ("Array", "Target", ))


@udf(returnType=ArrayType(DoubleType()))
def find_values_summing_to_target(array, target):
    def subset_sum(numbers, target, partial, result):
        s = sum(partial)
        # check if the partial sum is equals to target
        if s == target: 
            result.extend(partial)
        if s >= target:
            return  # if we reach the number why bother to continue
    
        for i in range(len(numbers)):
            n = numbers[i]
            remaining = numbers[i+1:]
            subset_sum(remaining, target, partial + [n], result)
    result = []
    if array is not None and target is not None:
        array = [Decimal(str(a)) for a in array]
        subset_sum(array, Decimal(str(target)), [], result)
        result = [float(r) for r in result]
    return result

df.withColumn("NewArray", find_values_summing_to_target("Array", "Target")).show(200, False)

输出

+--------------------------+------+--------------------+
|Array                     |Target|NewArray            |
+--------------------------+------+--------------------+
|[1.0E-4, 2.5, 3.0, 0.0031]|0.0032|[1.0E-4, 0.0031]    |
|[2.5, 1.0, 0.5, 3.0]      |3.0   |[2.5, 0.5, 3.0]     |
|[1.0, 1.0, 1.5, 1.0]      |4.5   |[1.0, 1.0, 1.5, 1.0]|
|[]                        |1.0   |[]                  |
|null                      |1.0   |[]                  |
|[1.0, 2.0]                |null  |[]                  |
+--------------------------+------+--------------------+
2021-11-29 17:22:52

感谢您的帮助,这肯定是把我放在正确的轨道。 但是我有麻烦在这一点:如果s>=目标:返回我得到一个错误的时候留在:类型错误:'>='不支持的实例之间'int'和'NoneType'. 当我把这个运行,但它不返回的所有数值总和的目标,只有1显示了当的价值是相等的目标本身。
Alex Triece

此外,该问题可能是小数我使用的是小得多(在.0031和达.0001范围)。 我注意到,当我取代的例子数据的小数这样它返回的空阵列。 任何想法?
Alex Triece

对于第一个问题,我认为你有没有值 target 列。 为此,我将更新的答案,返回的一个空阵列,如果发生这种情况。
Nithish

你绝对是对的第一个问题。 改变了na's0和它工作正常。 然而,它不阅读的较小数。 我很好用0的目标列,因此不需要花太多时间在这个问题,除非你想到对其他人的缘故。
Alex Triece

代码的答案是现在 nanull 安全。 为精确,我需要一个例子,我想对于较小的范围过6小数位数和它仍然有效。 一个例子将有助于复制。
Nithish

只是改变了的顶部的例子显示什么我看着,真的只是第一行。 当我这个,我得到正确的结果用于一切,除了顶排。
Alex Triece

该问题是由于漂浮点精度误差,在蟒蛇 0.0001 + 0.00310.0031999999999999997 stackoverflow.com/questions/11950819/python-math-is-wrong/...,我已经更新的答案,以支持精算术来支持你的用例.
Nithish

谢谢,这一帮助。 然而,它引发错误的小数()function. 是不是有什么需要的进口承认?
Alex Triece

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................