2016-12-14 53 views
0

我有型BinaryType的二進制列的表:提取字節

>>> df.show(3) 
+--------+--------------------+ 
|  t|    bytes| 
+--------+--------------------+ 
|0.145533|[10 50 04 89 00 3...| 
|0.345572|[60 94 05 89 80 9...| 
|0.545574|[99 50 68 89 00 7...| 
+--------+--------------------+ 
only showing top 3 rows 
>>> df.schema 
StructType(List(StructField(t,DoubleType,true),StructField(bytes,BinaryType,true))) 

如果我提取二進制的第一個字節,我從星火得到一個異常:

>>> df.select(n["t"], df["bytes"].getItem(0)).show(3) 
AnalysisException: u"Can't extract value from bytes#477;" 

強制轉換爲ArrayType(ByteType)也沒有工作:

>>> df.select(n["t"], df["bytes"].cast(ArrayType(ByteType())).getItem(0)).show(3) 
AnalysisException: u"cannot resolve '`bytes`' due to data type mismatch: cannot cast BinaryType to ArrayType(ByteType,true) ..." 

我怎樣才能提取字節?

回答

2

您可以爲一個簡單的UDF:

from pyspark.sql import functions as f 

a = bytearray([10, 50, 04]) 
df = sqlContext.createDataFrame([(1, a), (2, a)], ("t", "bytes")) 
df.show() 
+---+----------+ 
| t|  bytes| 
+---+----------+ 
| 1|[0A 32 04]| 
| 2|[0A 32 04]| 
+---+----------+ 
u = f.udf(lambda a: a[0]) 
df.select(u(df['bytes']).alias("first")).show() 
+-----+ 
|first| 
+-----+ 
| 10| 
| 10| 
+-----+ 

編輯

如果你想提取T的位置o是一個參數,你可以做一些currying:

func = lambda i: lambda a: a[i] 
my_udf = lambda i: f.udf(func(i)) 

df.select(my_udf(2)(df['bytes']).alias("last")).show() 

+----+ 
|last| 
+----+ 
| 4| 
| 4| 
+----+