Extrage valori dintr-o matrice această sumă la o anumită valoare pyspark

0

Problema

Am o dataframe care are o matrice cu dubleaza ca valori. În matrice, 1 sau o suma numerelor este egal cu o anumită valoare-țintă, și vreau pentru a extrage valorile care fie egală cu valoarea sau pot fi rezumate la egalitate de valoare. Mi-aș dori să fie în măsură să facă acest lucru în 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

Cel mai bun răspuns

1

Puteți îngloba logica ca un udf și de a crea NewArray bazat pe acest lucru. Am împrumutat logica pentru a identifica elementele de matrice bilanț la o valoare țintă de aici.


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)

Ieșire

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

Multumesc pentru ajutor, cu siguranta ma pui pe drumul cel bun. Cu toate acestea sunt probleme la acest punct: dacă s >= țintă: întoarcerea primesc o eroare atunci când a plecat în TypeError: '> = ' nu sunt acceptate între instanțe de 'int" și "NoneType'. Când m-am lua aceasta se execută, dar nu returnează toate valorile care suma la țintă, arată numai atunci când 1 de valori este egală cu ținta de la sine.
Alex Triece

În plus, problema ar putea fi faptul că zecimale folosesc sunt mult mai mici (în .0031 și .0001 gama). Am observat atunci când am înlocuit-o cu exemplul de date cu zecimale ca acest lucru este returnat gol tablouri. Orice gânduri pe care?
Alex Triece

Pentru prima problemă, cred că nu ai Nimic de valori în target coloana. Pentru asta eu va actualiza răspunsuri pentru a returna un array gol dacă acest lucru se întâmplă.
Nithish

Ai avut dreptate la prima problema. Schimbat na la 0 și funcționează bine. Cu toate acestea, nu citi mai mici zecimale. Eu sunt ok cu 0 în coloana țintă, astfel încât nu este nevoie să-și petreacă prea mult timp pe această temă, dacă doriți să pentru alții dumnezeu.
Alex Triece

Codul în care răspunsul este acum na sau null în condiții de siguranță. Pentru precizie, am nevoie de un exemplu, am încercat pentru intervale mai mici de asemenea cu 6 cifre zecimale și încă mai funcționează. Un exemplu ar ajuta replica.
Nithish

Schimbat doar partea de sus exemplu pentru a arăta ceea ce caut eu, de fapt doar primul rând. Atunci când am conectați acest lucru, am obține rezultate corecte pentru tot, cu excepția rândul de sus.
Alex Triece

Problema se datorează în virgulă mobilă de precizie eroare, în Python 0.0001 + 0.0031 este 0.0031999999999999997 stackoverflow.com/questions/11950819/python-math-is-wrong/..., am actualizat răspunde pentru a sprijini precizie aritmetică pentru a sprijini usecase.
Nithish

Multumesc, asta ajută. Cu toate acestea, ea aruncă o eroare cu Zecimale() funcție. Există ceva care trebuie să fie importate pentru a fi recunoscut?
Alex Triece

În alte limbi

Această pagină este în alte limbi

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