具有 pandas 等条件的 spark 数据集过滤器列
spark dataset filter column with conditions like pandas
我是 Spark/Scala 的新手。我不知道如何使用 spark 数据集来过滤像 pandas.loc.
这样的列
pandas代码:
data_fact = pd.read_excel(path, sheetname=sheetname_factor)
//drop some columns which have too many null value
data_fact_v1=data_fact.loc[:,((data_fact>0).sum()>len(data_fact) *0.7)]
非常感谢您的帮助!
我会为此使用 RDD,因为 API 更灵活。在下面的代码中,我将每一行映射到 tuple2 的列表,如果字段的值为 null,则列名关联到 0,否则关联到 1。然后我将所有内容展平并用 reduceByKey
计算每列非空值的数量。我最终删除了原始数据框中不符合您要求的列。
var data = ...
val cols = data.columns
val total = data.count
val nullMap = data.rdd
.flatMap{row => cols.filter(col => row.getAs(col) == null).map(col => (col, 1) ) }
.reduceByKey(_+_)
.collectAsMap
for(col <- cols)
if(nullMap.getOrElse(col, 0).toDouble / total < 0.7)
data = data.drop(col)
编辑其他方法:避免数据扁平化,可以使用聚合函数
def combine(map1 : Map[String, Int], map2 : Map[String, Int]) =
map1.keySet
.union(map2.keySet)
.map(k => (k, map1.getOrElse(k, 0)+map2.getOrElse(k, 0)))
.toMap
val nullMap = data.rdd.aggregate(Map[String, Int]())(
(map, row)=> combine(map, cols.filter(col => row.getAs(col) == null).map(col => (col, 1)).toMap),
combine)
然后一样
for(col <- cols)
if(nullMap.getOrElse(col, 0).toDouble / total >= 0.3)
data = data.drop(col)
或
val valid_columns = cols
.filter(col => nullMap.getOrElse(col, 0).toDouble / total >= 0.3)
data = data.drop(valid_columns : _*)
您可以遍历数据框的列并删除具有许多空值的列。
val cols = data.columns
val limit = data.count * 0.7
for(mycol <- cols){
if (data.filter(col(mycol).isNotNull).count < limit){
data = data.drop(mycol)
}
}
我是 Spark/Scala 的新手。我不知道如何使用 spark 数据集来过滤像 pandas.loc.
这样的列pandas代码:
data_fact = pd.read_excel(path, sheetname=sheetname_factor)
//drop some columns which have too many null value
data_fact_v1=data_fact.loc[:,((data_fact>0).sum()>len(data_fact) *0.7)]
非常感谢您的帮助!
我会为此使用 RDD,因为 API 更灵活。在下面的代码中,我将每一行映射到 tuple2 的列表,如果字段的值为 null,则列名关联到 0,否则关联到 1。然后我将所有内容展平并用 reduceByKey
计算每列非空值的数量。我最终删除了原始数据框中不符合您要求的列。
var data = ...
val cols = data.columns
val total = data.count
val nullMap = data.rdd
.flatMap{row => cols.filter(col => row.getAs(col) == null).map(col => (col, 1) ) }
.reduceByKey(_+_)
.collectAsMap
for(col <- cols)
if(nullMap.getOrElse(col, 0).toDouble / total < 0.7)
data = data.drop(col)
编辑其他方法:避免数据扁平化,可以使用聚合函数
def combine(map1 : Map[String, Int], map2 : Map[String, Int]) =
map1.keySet
.union(map2.keySet)
.map(k => (k, map1.getOrElse(k, 0)+map2.getOrElse(k, 0)))
.toMap
val nullMap = data.rdd.aggregate(Map[String, Int]())(
(map, row)=> combine(map, cols.filter(col => row.getAs(col) == null).map(col => (col, 1)).toMap),
combine)
然后一样
for(col <- cols)
if(nullMap.getOrElse(col, 0).toDouble / total >= 0.3)
data = data.drop(col)
或
val valid_columns = cols
.filter(col => nullMap.getOrElse(col, 0).toDouble / total >= 0.3)
data = data.drop(valid_columns : _*)
您可以遍历数据框的列并删除具有许多空值的列。
val cols = data.columns
val limit = data.count * 0.7
for(mycol <- cols){
if (data.filter(col(mycol).isNotNull).count < limit){
data = data.drop(mycol)
}
}