我想根据条件总结每行的列数。我找到了一种方法,但是当我有20多列要总结时似乎不是一个好主意,因为它会为每个列生成一个额外的列。
想要的结果是:以“_val”结尾的所有列的值总和,其中value为0或1(或<2,我只是想立即排除值3)
val df1 = Seq(
("id1", 1, 0, 3),
("id2", 0, 0, 3),
("id3", 1, 1, 3))
.toDF("id", "bla_val", "blub_val", "bli_val")
我希望的解决方案是列总和
val channelNames = df1.schema.fieldNames.filter(_.endsWith("_val"))
val ch = channelNames.map(x => col(x+"_redval"))
val df2 = df1.select(col("*") +: (channelNames.map(c =>
when(col(c) === 1, lit(1))
.otherwise(lit(0)).as(c+"_redval"))): _*)
val df3 = df2.withColumn("sum", ch.reduce(_+_))
df3.show()
输出示例:
id | bla_val | blub_val | bli_val | bla_val_redval | blub_val_redval | bli_val_redval | sum |
---|---|---|---|---|---|---|---|
id1 | 1 | 0 | 3 | 1 | 0 | 0 | 1 |
id2 | 0 | 0 | 3 | 0 | 0 | 0 | 0 |
id3 | 1 | 1 | 3 | 1 | 1 | 0 | 2 |
您可以使用reduce()操作组合表达式。看一下这个:
val df1 = Seq(
("id1", 1, 0, 3),
("id2", 0, 0, 3),
("id3", 1, 1, 3))
.toDF("id", "bla_val", "blub_val", "bli_val")
val newcols= df1.columns.filter(_.endsWith("_val")).map( x=> when(col(x)===1, lit(1)).otherwise(lit(0))).reduce(_+_)
df1.withColumn("redval_count",newcols).show(false)
输出:
id | bla_val | blub_val | bli_val | redval_count |
---|---|---|---|---|
id1 | 1 | 0 | 3 | 1 |
id2 | 0 | 0 | 3 | 0 |
id3 | 1 | 1 | 3 | 2 |
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。