Extrahovat hodnoty z pole částka do určité hodnoty pyspark

0

Otázka

Mám datovém že má pole s slouží jako hodnoty. Do pole, 1, nebo součet čísel se rovná určité cílové hodnoty, a chci extrahovat hodnoty, které buď stejné hodnoty, nebo mohou být sečteny, aby se rovnala hodnotě. Chtěl bych být schopen to udělat v 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

Nejlepší odpověď

1

Můžete zapouzdřit logiku jako udf a vytvořit NewArray na tomto základě. Půjčil jsem si logiku pro určení prvků pole shrneme-li, aby cílové hodnoty, z tu.


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)

Výstup

+--------------------------+------+--------------------+
|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

Díky za pomoc, určitě je to uvedení mě na správné cestě. Nicméně mám problém v tomto bodě: pokud s >= cíl: vrátit se dostanu chybu, když odešel v: TypeError: '>=' není podporováno mezi instancemi 'int' a 'NoneType'. Když jsem si to běží, ale to není návrat všech hodnot, že součet k cíli, pouze ukazuje, kdy 1 z hodnot je roven cíl sám o sobě.
Alex Triece

Navíc, problém může být, že desetinných čísel jsem pomocí jsou mnohem menší (v .0031 a .0001 rozsah). Všiml jsem si, když jsem vyměnil příklad údajů s desetinnými čísly, jako tohle je vráceno prázdné pole. Jakékoli myšlenky na to?
Alex Triece

Pro první vydání, myslím, že nemáte Žádné hodnoty v target sloupec. Pro to budu aktualizovat odpovědi, vrátit prázdné pole, pokud se to stane.
Nithish

Jsi naprostou pravdu, že první vydání. Změnil na 0 a funguje to v pohodě. Nicméně, to neznamená, číst menší počet desetinných míst. Jsem v pořádku s 0 je ve sloupci cíl, takže není třeba trávit příliš mnoho času na toto téma, pokud chcete, aby pro ostatní dobro.
Alex Triece

Kód v odpověď je teď na nebo null v bezpečí. Pro přesnost bych třeba příklad, snažil jsem se pro menší rozsahy taky 6 desetinných míst a to ještě funguje. Příkladem by mohl pomoci replikovat.
Nithish

Změnil horní příkladu ukázat, na co se dívám, opravdu jen první řádek. Když jsem to zapojit, jsem se dostat správné výsledky pro všechno, s výjimkou horní řádek.
Alex Triece

Problém je vzhledem k plovoucí bod přesnost chyby v Pythonu 0.0001 + 0.0031 je 0.0031999999999999997 stackoverflow.com/questions/11950819/python-math-is-wrong/..., mám aktualizováno odpověď na podporu přesné aritmetika pro podporu vašeho usecase.
Nithish

Díky, to pomáhá. Nicméně, to hází chybu s Desetinnou čárkou() funkce. Je tam něco, co musí být dovezeno pro které mají být uznána?
Alex Triece

V jiných jazycích

Tato stránka je v jiných jazycích

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