2016-07-05 21 views
8

Tôi muốn chuyển đổi từ một DataFrame chứa danh sách các từ thành một DataFrame với mỗi từ trong hàng của chính nó.Nổ trong PySpark

Làm cách nào để phát nổ trên một cột trong DataFrame?

Dưới đây là ví dụ về một số nỗ lực của tôi, nơi bạn có thể bỏ ghi chú cho từng dòng mã và nhận được lỗi được liệt kê trong nhận xét sau. Tôi sử dụng PySpark trong Python 2.7 với Spark 1.6.1.

from pyspark.sql.functions import split, explode 
DF = sqlContext.createDataFrame([('cat \n\n elephant rat \n rat cat',)], ['word']) 
print 'Dataset:' 
DF.show() 
print '\n\n Trying to do explode: \n' 
DFsplit_explode = (
DF 
.select(split(DF['word'], ' ')) 
# .select(explode(DF['word'])) # AnalysisException: u"cannot resolve 'explode(word)' due to data type mismatch: input to function explode should be array or map type, not StringType;" 
# .map(explode) # AttributeError: 'PipelinedRDD' object has no attribute 'show' 
# .explode() # AttributeError: 'DataFrame' object has no attribute 'explode' 
).show() 

# Trying without split 
print '\n\n Only explode: \n' 

DFsplit_explode = (
DF 
.select(explode(DF['word'])) # AnalysisException: u"cannot resolve 'explode(word)' due to data type mismatch: input to function explode should be array or map type, not StringType;" 
).show() 

Xin tư vấn

Trả lời

13

explodesplit là hàm SQL. Cả hai hoạt động trên SQL Column. split sử dụng biểu thức chính quy Java làm đối số thứ hai. Nếu bạn muốn dữ liệu trên khoảng trắng tùy ý tách bạn sẽ cần một cái gì đó như thế này:

df = sqlContext.createDataFrame(
    [('cat \n\n elephant rat \n rat cat',)], ['word'] 
) 

df.select(explode(split(col("word"), "\s+")).alias("word")).show() 

## +--------+ 
## | word| 
## +--------+ 
## |  cat| 
## |elephant| 
## |  rat| 
## |  rat| 
## |  cat| 
## +--------+ 
6

Để chia vào khoảng trắng và cũng loại bỏ các dòng trống, thêm mệnh đề where.

DF = sqlContext.createDataFrame([('cat \n\n elephant rat \n rat cat\nmat\n',)], ['word']) 

>>> (DF.select(explode(split(DF.word, "\s")).alias("word")) 
     .where('word != ""') 
     .show()) 

+--------+ 
| word| 
+--------+ 
|  cat| 
|elephant| 
|  rat| 
|  rat| 
|  cat| 
|  mat| 
+--------+ 
+0

Cảm ơn bạn đã thêm điều khoản where. – user1982118

+1

Đối với một giải pháp hoàn chỉnh hơn một chút có thể khái quát hóa các trường hợp có nhiều hơn một cột phải được báo cáo, hãy sử dụng 'withColumn' thay vì 'chọn' đơn giản: df.withColumn ('word', explode ('word')) .show() Điều này đảm bảo rằng tất cả các phần còn lại của các cột trong DataFrame vẫn có mặt trong DataFrame đầu ra, sau khi sử dụng phát nổ. Điều này cũng đơn giản hơn việc chỉ định từng cột cần được chọn, tức là: df.select ('col1', 'col2', ..., 'colN', phát nổ ('từ')). Hiển thị() –