我正在尝试在Spark 2.0.0中的Dataset[Row]
(DataFrame
)上执行简单的地图。像这个简单的东西
val df: DataSet[Row] = ...
df.map { r: Row => r }
但编译器抱怨我没有向map函数提供隐式Encoder[Row]
参数:
方法图没有足够的参数:(隐式证据$ 7: 编码器[行])。
如果我首先转换为RDD ds.rdd.map { r: Row => r }
,那么一切正常,但是不应该有一种简单的方法来获取Encoder[Row]
,就像元组类型Encoders.product[(Int, Double)]
一样?
[请注意,我的Row
动态调整大小,无法轻松转换为强类型Dataset
。]
答案 0 :(得分:1)
0,1=> as above 2=> 0+2*2 1+2*2 3=> 0+2*3 1+2*3
1+2*2 0+2*2 1+2*3 0+2*3
需要知道如何将元素打包到// i: row, j: column, n: matrix dimension
var v = 0;
var m = 2;
do
{
var p = m/2;
v = v*2 + (i%(n/p) < n/m == j%(n/p) < n/m ? 0 : 1);
m *= 2;
} while (m <= n);
中。因此,您可以使用Encoder
编写自己的Row
,Encoder[Row]
在运行时确定row.structType
的元素并使用相应的解码器。
如果您对Row
中的数据有更多了解,可以使用https://github.com/adelbertc/frameless/
答案 1 :(得分:0)
很晚才成为“位”。希望这对现在遇到问题的人有所帮助。定义编码器的最简单方法是从现有DataFrame派生结构:
val df = Seq((1, "a"), (2, "b"), (3, "c").toDF("id", "name")
val myEncoder = RowEndocer(df.schema)
当您需要更改原始DataFrame中的现有字段时,这种方法可能会有用。
如果您要处理全新的结构,则显式定义依赖于StructType
和StructField
(如@Reactormonk的一点神秘反应所建议)。
定义相同编码器的示例:
val myEncoder2 = RowEncoder(StructType(
Seq(StructField("id", IntegerType),
StructField("name", StringType)
)))
请记住,必须导入org.apache.spark.sql._
,org.apache.spark.sql.types._
和org.apache.spark.sql.catalyst.encoders.RowEncoder
库。