Belirli bir pyspark değerine toplanan bir diziden değerleri ayıkla

0

Soru

Değer olarak iki katına sahip bir diziye sahip bir veri çerçevem var. Dizinin içinde, 1 veya sayıların toplamı belirli bir hedef değere eşittir ve değere eşit olan veya değere eşit olacak şekilde toplanabilen değerleri çıkarmak istiyorum. Bunu Pyspark'ta yapabilmek istiyorum.

| 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

En iyi cevabı

1

Mantığı şu şekilde kapsülleyebilirsiniz:udf ve yarat NewArray buna dayanarak. Buradan bir hedef değere dizi toplama öğelerini tanımlamak için mantığı ödünç aldım.


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)

Çıktı

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

Yardımın için teşekkürler, kesinlikle beni doğru yola sokuyor. Ancak şu anda sorun yaşıyorum: eğer s >= target: return İçinde bırakıldığında bir hata alıyorum: TypeError: '> > = '' int 've'NoneType' örnekleri arasında desteklenmiyor. Bunu çıkardığımda çalışır, ancak hedefe toplam değerlerin tümünü döndürmez, yalnızca değerlerin 1'inin kendi başına hedefe eşit olduğunu gösterir.
Alex Triece

Ayrıca, sorun, kullandığım ondalıkların çok daha küçük olması olabilir .0031 ve .0001 aralığı). Örnek verileri bunun gibi ondalık sayılarla değiştirdiğimde boş diziler döndürdüğünü fark ettim. Bu konuda herhangi bir düşünce?
Alex Triece

İlk sayı için, hiçbir değeriniz olmadığını düşünüyorum target sütun. Bunun için, bu gerçekleşirse boş bir dizi döndürmek için cevapları güncelleyeceğim.
Nithish

İlk sayı konusunda kesinlikle haklıydın. Na'ları 0 olarak değiştirdi ve iyi çalışıyor. Ancak, daha küçük ondalık okumaz. Hedef sütunda 0'larla iyiyim, bu yüzden başkalarının iyiliği için istemediğiniz sürece bu konuda çok fazla zaman harcamanıza gerek yok.
Alex Triece

Cevaptaki kod şimdi na veya null güvenli. Kesinlik için bir örneğe ihtiyacım olacak, daha küçük aralıklar için de 6 ondalık basamak denedim ve hala çalışıyor. Bir örnek çoğaltmaya yardımcı olacaktır.
Nithish

Baktığım şeyi göstermek için en üstteki örneği değiştirdim, gerçekten sadece ilk satır. Bunu taktığımda, üst satır dışındaki her şey için doğru sonuçlar alıyorum.
Alex Triece

Sorun, Python'da kayan nokta hassasiyeti hatasından kaynaklanıyor 0.0001 + 0.0031 oluyor 0.0031999999999999997 stackoverflow.com/questions/11950819/python-math-is-wrong/..., Kullanım durumunuzu desteklemek için hassas aritmetiği desteklemek için cevabı güncelledim.
Nithish

Teşekkürler, yardımı dokunur. Ancak, Decimal () işleviyle bir hata atar. Bunun tanınması için ithal edilmesi gereken bir şey var mı?
Alex Triece

Diğer dillerde

Bu sayfa diğer dillerde

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