Birden çok veri çerçevesinin PySpark'ta sırayla birleştirilmesi


21

Ben 10 veri çerçeveleri var pyspark.sql.dataframe.DataFrameelde, randomSplityanı (td1, td2, td3, td4, td5, td6, td7, td8, td9, td10) = td.randomSplit([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1], seed = 100)Şimdi 9 katılmak istiyorum tdbunu nasıl, tek bir veri çerçevesi içine s'?

Ben zaten denedim unionAll, ancak bu işlev sadece iki argüman kabul eder.

td1_2 = td1.unionAll(td2) 
# this is working fine

td1_2_3 = td1.unionAll(td2, td3) 
# error TypeError: unionAll() takes exactly 2 arguments (3 given)

İkiden fazla veri çerçevesini sırayla birleştirmenin bir yolu var mı?

Bunu yapmanın amacı, PySpark CrossValidatoryöntemini kullanmadan elle 10 kat Çapraz Doğrulama yapmak , 9'u eğitime ve 1'i test verisine almak ve ardından diğer kombinasyonlar için tekrarlayacağım.


1
Bu doğrudan soruyu cevaplamıyor, ama işte isimlendirme yöntemini geliştirmek için bir öneride bulunuyorum, böylece sonunda, şunu yazmamız gerekmiyor, örneğin: [td1, td2, td3, td4, td5, td6, td7 , td8, td9, td10]. Bunu 100 kat CV için yaptığınızı düşünün. İşte ne yapacağım: porsiyon = [0,1] * 10 cv = df7.randomSplit (porsiyon) katlar = (i) (10) aralığındaki i listesi için (aralık (10)): test_data = cv [i] fold_no_i = folds [: i] + kıvrımları [i + 1:] train_data = cv [fold_no_i [0]] j içinde fold_no_i [1:]: train_data = train_data.union (cv [j])
ngoc thoag

Yanıtlar:


37

Çalıntı: /programming/33743978/spark-union-of-multiple-rdds

Zincirleme sendikaların dışında, DataFrames için bunu yapmanın tek yolu budur.

from functools import reduce  # For Python 3.x
from pyspark.sql import DataFrame

def unionAll(*dfs):
    return reduce(DataFrame.unionAll, dfs)

unionAll(td2, td3, td4, td5, td6, td7, td8, td9, td10)

Olan şey, parametre olarak ilettiğiniz tüm nesneleri alıp bunları unionAll kullanarak indirgemesidir (bu azalma Python'dan kaynaklanır, benzer şekilde çalışsalar bile Spark azaltmaz), bu da sonunda bir DataFrame'e indirgenir.

DataFrames yerine normal RDD'lerse, bunların bir listesini SparkContext'in birleştirme işlevine aktarabilirsiniz.

EDIT: Amacınız için farklı bir yöntem öneriyorum, çünkü bu bütün birliği çapraz katlama için farklı katlarınız için 10 kez tekrarlamanız gerekeceğinden, bir satırın katlanacağı etiketleri ekleyeceğim ve sadece her kat için DataFrame'inizi filtreleyeceğim. etiket


(+1) Etrafta güzel bir çalışma. Bununla birlikte, çoklu veri çerçevelerinin birleştirilmesine izin veren bir fonksiyonun olması gerekir. Oldukça kullanışlı olurdu!
Dawny33

Buna katılmıyorum
Jan van der Vegt

@JanvanderVegt Teşekkürler, çalışıyor ve eğitim ve test veri setini filtrelemek için etiket ekleme fikri çoktan yaptım. Yardımın için çok teşekkürler.
krishna Prasad

@Jan van der Vegt Lütfen aynı mantığı uygulayabilir misiniz? Bu soruyu cevaplayın
GeorgeOfTheRF


6

Bazen, birleştirilecek veri çerçeveleri aynı sütun sırasına sahip olmadığında, her iki df'nin birleşimden önce aynı sütun sırasına sahip olmasını sağlamak için df2.select (df1.columns) seçeneğine göre daha iyidir.

import functools 

def unionAll(dfs):
    return functools.reduce(lambda df1,df2: df1.union(df2.select(df1.columns)), dfs) 

Örnek:

df1 = spark.createDataFrame([[1,1],[2,2]],['a','b'])
# different column order. 
df2 = spark.createDataFrame([[3,333],[4,444]],['b','a']) 
df3 = spark.createDataFrame([555,5],[666,6]],['b','a']) 

unioned_df = unionAll([df1, df2, df3])
unioned_df.show() 

görüntü tanımını buraya girin

Aksi takdirde bunun yerine aşağıdaki sonucu üretecektir.

from functools import reduce  # For Python 3.x
from pyspark.sql import DataFrame

def unionAll(*dfs):
    return reduce(DataFrame.unionAll, dfs) 

unionAll(*[df1, df2, df3]).show()

görüntü tanımını buraya girin


2

Özyineleme kullanmaya ne dersiniz?

def union_all(dfs):
    if len(dfs) > 1:
        return dfs[0].unionAll(union_all(dfs[1:]))
    else:
        return dfs[0]

td = union_all([td1, td2, td3, td4, td5, td6, td7, td8, td9, td10])
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.