当前位置: 首页 > 科技观察

如何从Spark的DataFrame中提取特定行?

时间:2023-03-20 12:45:11 科技观察

如何从Spark的DataFrame中提取特定行?阿里专家认为Spark的DataFrame不是真正的DataFrame-秦旭烨的文章-知乎[1]文章:DataFrame应该有“保证顺序、行列对称”等规则《SparkDataFrame和Koalas不是真正的DataFrame》"确实可以运行,但是看到一句话,大意是将数据放在一个partition中执行。这正是因为数据本身的顺序是不能保证的,所以我们只能把数据收集在一起,排序,调用shift。这不再是分布式程序,甚至比pandas本身还要慢。我们可以明确一个前提:Spark中的DataFrame是RDD的扩展,受限于其分布式和弹性内存的特性,我们不能直接执行类似df.iloc(r,c)的操作来提取某一行。但是现在我有一个需求,binning。具体来说,需要“遍历排序后的每一行及其邻居如i、i+j”。因此,我们必须能够获取到某行数据!不知道有没有高手可以帮忙方法?我只是想到了以下技巧!1/3排序后select再collectcollect就是把DataFrame转成数组放到内存中。但是Spark处理的数据一般都非常大,如果直接转成数组的话,内存会爆炸。因此不能直接收集。处理哪一列,直接select('列名')取出这一列,然后收集即可。我的数据有2e5*2e4之多,所以select之后只有一列大小为2e5*1,还是可以采集的。这显然不是一个好方法!因为它无法处理真正大的数据,例如当有很多行时。2/3排序后,添加索引,使用SQL查找DataFrame实例。sort("columnname")后,用SQL语句查找:selectcolumnnamefromdf_tablewhereindexcolumnname=i我对SQL了解不多,所以这个方法只是在idea阶段。另外,我不知道SQL的性能!我必须多次调用df.iloc[i,column],所以它会不会太慢?3/3排序,加索引然后转置查找列名就卡在头上了!因为这会很困难。每行添加一个索引列,从0开始计数,然后转置矩阵,索引列作为新的列名。然后取第i个数字,只需df(i.toString)即可。这种方法似乎是可靠的。附加解决方案:ml.feature.Bucketizerimportorg.apache.spark.ml.feature.{Bucketizer,QuantileDiscretizer}spark中Bucketizer的功能和我实现的需求差不多(虽然细节不同),我猜应??该也有类似的逻辑。有能力有精力的还是去读源码,看看官方是怎么实现的。参考文献[1]Spark的DataFrame不是真正的DataFrame——秦旭野的文章——知乎:https://zhuanlan.zhihu.com/p/135329592