2017-06-27 185 views
0

我有一個關於數據框的基本問題,並添加了一個應該包含嵌套列表的列。這是基本的問題:Pyspark/Dataframe:添加將列表嵌套列表作爲嵌套列表的新列

b = [[['url.de'],['name']],[['url2.de'],['name2']]] 

a = sc.parallelize(b) 
a = a.map(lambda p: Row(URL=p[0],name=p[1])) 
df = sqlContext.createDataFrame(a) 

list1 = [[['a','s', 'o'],['hallo','ti']],[['a','s', 'o'],['hallo','ti']]] 
c = [b[0] + [list1[0]],b[1] + [list1[1]]] 

#Output looks like this: 
[[['url.de'], ['name'], [['a', 's', 'o'], ['hallo', 'ti']]], 
[['url2.de'], ['name2'], [['a', 's', 'o'], ['hallo', 'ti']]]] 

創建從這個輸出一個新的數據幀,我正嘗試建立一個新的模式:

schema = df.withColumn('NewColumn',array(lit("10"))).schema 

然後我用它來創建新的數據框:

df = sqlContext.createDataFrame(c,schema) 
df.map(lambda x: x).collect() 

#Output 
[Row(URL=[u'url.de'], name=[u'name'], NewColumn=[u'[a, s, o]', u'[hallo, ti]']), 
Row(URL=[u'url2.de'], name=[u'name2'], NewColumn=[u'[a, s, o]', u'[hallo, ti]'])] 

現在的問題是,嵌套列表被轉換成有兩個unicode條目的列表,而不是保持原始格式。

我認爲這是由於我對新列「... array(lit(」10「))」的定義。

爲了保持原始格式,我必須使用什麼?

+0

DF [ 'NewColumn'] astype可以通過顯式定義模式做到這一點(str).values從列值中刪除unicode。 – Anup

+0

不起作用:「TypeError:unexpected type:」。而我不想要一個字符串作爲結果我想要嵌套列表作爲結果 – mgruber

回答

1

您可以通過調用df.schema直接檢查數據幀的模式。你可以看到,在給定的情況下,我們有以下幾點:您添加

StructType(
    List(
    StructField(URL,ArrayType(StringType,true),true), 
    StructField(name,ArrayType(StringType,true),true), 
    StructField(NewColumn,ArrayType(StringType,false),false) 
) 
) 

NewColumnArrayType列,其條目是所有StringType。所以包含在數組中的任何東西都會被轉換爲一個字符串,即使它本身就是一個數組。如果您想要嵌套數組(2層),則需要更改模式,以使NewColumn字段的類型爲ArrayType(ArrayType(StringType,False),False)

from pyspark.sql.types import StructType, StructField, ArrayType, StringType 

schema = StructType([ 
    StructField("URL", ArrayType(StringType(),True), True), 
    StructField("name", ArrayType(StringType(),True), True), 
    StructField("NewColumn", ArrayType(ArrayType(StringType(),False),False), False)]) 

或由具有NewColumn改變通過嵌套array功能,array(array())定義代碼:。

df.withColumn('NewColumn',array(array(lit("10")))).schema 
+0

非常感謝!豎起大拇指!沒有想到這樣做的簡單方法。 – mgruber