Hợp nhất nhiều khung dữ liệu theo hàng trong PySpark


21

Tôi có khung 10 dữ liệu pyspark.sql.dataframe.DataFrame, thu được từ randomSplitnhư (td1, td2, td3, td4, td5, td6, td7, td8, td9, td10) = td.randomSplit([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1], seed = 100)Bây giờ tôi muốn tham gia 9 tdlà vào một khung dữ liệu duy nhất, làm thế nào tôi nên làm điều đó?

Tôi đã thử với unionAll, nhưng hàm này chỉ chấp nhận hai đối số.

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)

Có cách nào để kết hợp nhiều hơn hai khung dữ liệu theo hàng không?

Mục đích của việc này là tôi đang thực hiện Xác thực chéo 10 lần theo cách thủ công mà không sử dụng CrossValidatorphương pháp PySpark , vì vậy, đưa 9 vào đào tạo và 1 vào dữ liệu thử nghiệm và sau đó tôi sẽ lặp lại nó cho các kết hợp khác.


1
Điều này không trả lời trực tiếp câu hỏi, nhưng ở đây tôi đưa ra một gợi ý để cải thiện phương thức đặt tên để cuối cùng, chúng ta không phải gõ, ví dụ: [td1, td2, td3, td4, td5, td6, td7 , td8, td9, td10]. Hãy tưởng tượng làm điều này cho một CV gấp 100 lần. Đây là những gì tôi sẽ làm: các phần = [0,1] * 10 cv = df7.randomSplit (các phần) Folds = list (phạm vi (10)) cho i trong phạm vi (10): test_data = cv [i] Fold_no_i = Folds [: i] + nếp gấp [i + 1:] train_data = cv [Fold_no_i [0]] cho j trong Fold_no_i [1:]: train_data = train_data.union (cv [j])
ngoc thoag

Câu trả lời:


37

Bị đánh cắp từ: /programming/33743978/spark-union-of-multipl-rdds

Bên ngoài các chuỗi liên kết, đây là cách duy nhất để làm điều đó cho DataFrames.

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)

Điều xảy ra là nó lấy tất cả các đối tượng mà bạn đã truyền làm tham số và giảm chúng bằng cách sử dụng unionAll (phần giảm này là từ Python, không phải là Spark giảm mặc dù chúng hoạt động tương tự nhau) cuối cùng sẽ giảm nó thành một DataFrame.

Nếu thay vì DataFrames, chúng là RDD bình thường, bạn có thể chuyển danh sách của chúng cho hàm kết hợp của SparkContext của bạn

EDIT: Với mục đích của bạn, tôi đề xuất một phương pháp khác, vì bạn sẽ phải lặp lại toàn bộ liên minh này 10 lần cho các nếp gấp khác nhau của bạn để xác định giá trị chéo, tôi sẽ thêm các nhãn cho một hàng gấp và chỉ lọc DataFrame của bạn cho mỗi lần dựa trên nhãn


(+1) Một công việc tốt. Tuy nhiên, cần phải có một chức năng cho phép ghép nhiều dataframes. Sẽ khá tiện dụng!
Dawny33

Tôi không đồng ý với điều đó
Jan van der Vegt

@JanvanderVegt Cảm ơn, nó hoạt động và ý tưởng thêm nhãn để lọc ra tập dữ liệu đào tạo và thử nghiệm, tôi đã thực hiện nó. Cảm ơn bạn rất nhiều vì đã giúp đỡ của bạn.
krishna Prasad

@Jan van der Vegt Bạn có thể vui lòng áp dụng logic tương tự cho Tham gia và trả lời câu hỏi này không
GeorgeOfTheRF


6

Đôi khi, khi các datafram kết hợp không có cùng thứ tự các cột, tốt hơn là df2.select (df1.columns) để đảm bảo cả hai df có cùng thứ tự cột trước khi kết hợp.

import functools 

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

Thí dụ:

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() 

nhập mô tả hình ảnh ở đây

nếu không nó sẽ tạo ra kết quả dưới đây thay thế.

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()

nhập mô tả hình ảnh ở đây


2

Làm thế nào về việc sử dụng đệ quy?

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])
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.