Výpis hodnoty z poľa, že suma do určitej hodnoty pyspark

0

Otázka

Mám dataframe, ktorý má pole s, slúži aj ako hodnoty. V rámci poľa, 1 alebo súčet čísel sa rovná určitú cieľovú hodnotu, a chcem výpis hodnoty, ktoré buď rovnakú hodnotu, alebo môžu byť sumarizované na rovnakú hodnotu. Ja by som chcel byť schopní to urobiť 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

Najlepšiu odpoveď

1

Môžete zapuzdrenia logika ako udf a vytvoriť NewArray na tomto základe. Som si požičal logiky na identifikáciu prvkov poľa sčítanie do cieľová hodnota od 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

Vďaka za vašu pomoc, je to určite uvedenie ma na správnu cestu. Však som problémy v tomto bode: ak s >= cieľ: vrátiť sa dostanem chybu, keď odišiel v: TypeError: '>=' nie je podporovaný medzi inštancie 'int" a "NoneType'. Keď som sa na to, že beží, ale nie je návrat všetkých hodnôt, ktoré súčtom k cieľu, zobrazí iba pri 1 z hodnoty je rovnaký ako cieľ sám o sebe.
Alex Triece

Navyše, problém môže byť, že desatinné miesta používam sú oveľa menšie (v .0031 a .0001 rozsah). Všimol som si, keď som nahrádzali údaje príklad s desatinnými číslami, ako je to vracia prázdne polia. Akékoľvek myšlienky na to?
Alex Triece

Pre prvé vydanie, myslím, že ste Žiadne hodnoty v target stĺpec. Ja som sa bude aktualizovať odpovede vrátiť prázdne pole, ak sa to stane.
Nithish

Boli ste úplne v poriadku o tom, že prvé vydanie. Zmenili na to, aby sa 0 a funguje to v pohode. Avšak, to neprečíta menšie desatinné miesta. Ja som ok s 0 v cieľovej stĺpci, takže nie je potrebné stráviť príliš veľa času na to, že problém, pokiaľ nechcete, aby sa pre druhých ľudí.
Alex Triece

Kód odpoveď je teraz na alebo null bezpečné. Pre presné potreboval by som príklad, snažil som sa pre menšie rozsahy príliš 6 desatinných čísel a stále to funguje. Príkladom môže pomôcť replikovať.
Nithish

Stačí zmeniť hornej príklade ukázať, čo som si pri pohľade na, naozaj len prvý riadok. Keď som zapojte tento, som si správne výsledky pre všetko okrem hornom riadku.
Alex Triece

Problém je v dôsledku pohyblivou rádovou čiarkou presnosť chyba, v jazyku Python 0.0001 + 0.0031 je 0.0031999999999999997 stackoverflow.com/questions/11950819/python-math-is-wrong/..., som aktualizoval odpoveď na podporu presnosť aritmetický na podporu vášho usecase.
Nithish

Vďaka, že pomáha. To však vyvolá chybovú s Čiarku() funkcia. Je tam niečo, čo musí byť dovezené na to, aby boli uznané?
Alex Triece

V iných jazykoch

Táto stránka je v iných jazykoch

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