[SCALA] 스파크 dataframe로부터 NULL 값을 필터링하는 방법
SCALA스파크 dataframe로부터 NULL 값을 필터링하는 방법
나는 다음과 같은 스키마와 스파크에 dataframe을 만들어 :
root
|-- user_id: long (nullable = false)
|-- event_id: long (nullable = false)
|-- invited: integer (nullable = false)
|-- day_diff: long (nullable = true)
|-- interested: integer (nullable = false)
|-- event_owner: long (nullable = false)
|-- friend_id: long (nullable = false)
그리고 데이터는 다음과 같습니다 :
+----------+----------+-------+--------+----------+-----------+---------+
| user_id| event_id|invited|day_diff|interested|event_owner|friend_id|
+----------+----------+-------+--------+----------+-----------+---------+
| 4236494| 110357109| 0| -1| 0| 937597069| null|
| 78065188| 498404626| 0| 0| 0| 2904922087| null|
| 282487230|2520855981| 0| 28| 0| 3749735525| null|
| 335269852|1641491432| 0| 2| 0| 1490350911| null|
| 437050836|1238456614| 0| 2| 0| 991277599| null|
| 447244169|2095085551| 0| -1| 0| 1579858878| null|
| 516353916|1076364848| 0| 3| 1| 3597645735| null|
| 528218683|1151525474| 0| 1| 0| 3433080956| null|
| 531967718|3632072502| 0| 1| 0| 3863085861| null|
| 627948360|2823119321| 0| 0| 0| 4092665803| null|
| 811791433|3513954032| 0| 2| 0| 415464198| null|
| 830686203| 99027353| 0| 0| 0| 3549822604| null|
|1008893291|1115453150| 0| 2| 0| 2245155244| null|
|1239364869|2824096896| 0| 2| 1| 2579294650| null|
|1287950172|1076364848| 0| 0| 0| 3597645735| null|
|1345896548|2658555390| 0| 1| 0| 2025118823| null|
|1354205322|2564682277| 0| 3| 0| 2563033185| null|
|1408344828|1255629030| 0| -1| 1| 804901063| null|
|1452633375|1334001859| 0| 4| 0| 1488588320| null|
|1625052108|3297535757| 0| 3| 0| 1972598895| null|
+----------+----------+-------+--------+----------+-----------+---------+
나는 행이 "friend_id"의 필드에 null 값을 필터링 할.
scala> val aaa = test.filter("friend_id is null")
scala> aaa.count
내가 가지고 : res52 : 김 = 0 명확하지 권리입니다. 그것을 얻을 수있는 올바른 방법은 무엇입니까?
또 하나의 문제는, 나는 friend_id 필드의 값을 대체합니다. 내가 널 제외한 다른 값을 0과 1로 널 (null)을 대체합니다. 내가 알아낼 수있는 코드는 다음과 같습니다
val aaa = train_friend_join.select($"user_id", $"event_id", $"invited", $"day_diff", $"interested", $"event_owner", ($"friend_id" != null)?1:0)
이 코드는 작동하지 않습니다. 나는이 문제를 해결할 수있는 방법을 사람이 말해 줄래? 감사
해결법
-
==============================
1.하자 당신이 데이터 설정을 (결과가 재현 그래서)가 있다고 가정 :
하자 당신이 데이터 설정을 (결과가 재현 그래서)가 있다고 가정 :
// declaring data types case class Company(cName: String, cId: String, details: String) case class Employee(name: String, id: String, email: String, company: Company) // setting up example data val e1 = Employee("n1", null, "n1@c1.com", Company("c1", "1", "d1")) val e2 = Employee("n2", "2", "n2@c1.com", Company("c1", "1", "d1")) val e3 = Employee("n3", "3", "n3@c1.com", Company("c1", "1", "d1")) val e4 = Employee("n4", "4", "n4@c2.com", Company("c2", "2", "d2")) val e5 = Employee("n5", null, "n5@c2.com", Company("c2", "2", "d2")) val e6 = Employee("n6", "6", "n6@c2.com", Company("c2", "2", "d2")) val e7 = Employee("n7", "7", "n7@c3.com", Company("c3", "3", "d3")) val e8 = Employee("n8", "8", "n8@c3.com", Company("c3", "3", "d3")) val employees = Seq(e1, e2, e3, e4, e5, e6, e7, e8) val df = sc.parallelize(employees).toDF
데이터는 다음과 같습니다
+----+----+---------+---------+ |name| id| email| company| +----+----+---------+---------+ | n1|null|n1@c1.com|[c1,1,d1]| | n2| 2|n2@c1.com|[c1,1,d1]| | n3| 3|n3@c1.com|[c1,1,d1]| | n4| 4|n4@c2.com|[c2,2,d2]| | n5|null|n5@c2.com|[c2,2,d2]| | n6| 6|n6@c2.com|[c2,2,d2]| | n7| 7|n7@c3.com|[c3,3,d3]| | n8| 8|n8@c3.com|[c3,3,d3]| +----+----+---------+---------+
이제 널 ID를 가진 필터 직원, 당신이 할 것입니다 -
df.filter("id is null").show
올바르게 다음을 보여줄 것이다 :
+----+----+---------+---------+ |name| id| email| company| +----+----+---------+---------+ | n1|null|n1@c1.com|[c1,1,d1]| | n5|null|n5@c2.com|[c2,2,d2]| +----+----+---------+---------+
질문의 두 번째 부분에오고,이 1로 널 0 ID와 다른 값을 대체 할 수 있습니다 -
df.withColumn("id", when($"id".isNull, 0).otherwise(1)).show
이 결과 :
+----+---+---------+---------+ |name| id| email| company| +----+---+---------+---------+ | n1| 0|n1@c1.com|[c1,1,d1]| | n2| 1|n2@c1.com|[c1,1,d1]| | n3| 1|n3@c1.com|[c1,1,d1]| | n4| 1|n4@c2.com|[c2,2,d2]| | n5| 0|n5@c2.com|[c2,2,d2]| | n6| 1|n6@c2.com|[c2,2,d2]| | n7| 1|n7@c3.com|[c3,3,d3]| | n8| 1|n8@c3.com|[c3,3,d3]| +----+---+---------+---------+
-
==============================
2.또는 df.filter처럼 ($ .isNotNull "friend_id")
또는 df.filter처럼 ($ .isNotNull "friend_id")
-
==============================
3.
df.where(df.col("friend_id").isNull)
-
==============================
4.나를 위해 좋은 솔루션에 null 값으로 행을 드롭했다 :
나를 위해 좋은 솔루션에 null 값으로 행을 드롭했다 :
데이터 집합 <행> = 필터링 df.filter (행 => row.anyNull!);
경우 하나가 다른 경우 관심, 그냥 row.anyNull를 호출합니다. (스파크 2.1.0 사용하는 Java API)
-
==============================
5.필터 조건 1) 수동 2) 동적를 만들기 : 그것을 할 방법은 두 가지가 있습니다.
필터 조건 1) 수동 2) 동적를 만들기 : 그것을 할 방법은 두 가지가 있습니다.
샘플 DataFrame :
val df = spark.createDataFrame(Seq( (0, "a1", "b1", "c1", "d1"), (1, "a2", "b2", "c2", "d2"), (2, "a3", "b3", null, "d3"), (3, "a4", null, "c4", "d4"), (4, null, "b5", "c5", "d5") )).toDF("id", "col1", "col2", "col3", "col4") +---+----+----+----+----+ | id|col1|col2|col3|col4| +---+----+----+----+----+ | 0| a1| b1| c1| d1| | 1| a2| b2| c2| d2| | 2| a3| b3|null| d3| | 3| a4|null| c4| d4| | 4|null| b5| c5| d5| +---+----+----+----+----+
즉 DataFrame 또는 필터 함수를 사용하여 수동 1) 작성 필터 조건
df.filter(col("col1").isNotNull && col("col2").isNotNull).show
또는
df.where("col1 is not null and col2 is not null").show
결과:
+---+----+----+----+----+ | id|col1|col2|col3|col4| +---+----+----+----+----+ | 0| a1| b1| c1| d1| | 1| a2| b2| c2| d2| | 2| a3| b3|null| d3| +---+----+----+----+----+
2) 동적 필터 조건을 만들기 : 우리는 모든 열이 null 값을 갖고 싶어하지 않고 대부분의 경우 열 많은 수의,있을 때 유용하다.
이러한 경우 수동 필터 조건을 만들려면 많은 시간을 낭비합니다. 코드 아래에 우리가 동적으로지도를 사용하고 DataFrame 컬럼에 기능을 줄이고 모든 열을 포함하고 있습니다에서 :
val filterCond = df.columns.map(x=>col(x).isNotNull).reduce(_ && _)
어떻게 filterCond 보이는 :
filterCond: org.apache.spark.sql.Column = (((((id IS NOT NULL) AND (col1 IS NOT NULL)) AND (col2 IS NOT NULL)) AND (col3 IS NOT NULL)) AND (col4 IS NOT NULL))
필터링 :
val filteredDf = df.filter(filterCond)
결과:
+---+----+----+----+----+ | id|col1|col2|col3|col4| +---+----+----+----+----+ | 0| a1| b1| c1| d1| | 1| a2| b2| c2| d2| +---+----+----+----+----+
-
==============================
6.마이클 Kopaniov에서, 작품 아래 힌트에서
마이클 Kopaniov에서, 작품 아래 힌트에서
df.where(df("id").isNotNull).show
-
==============================
7.여기에 자바에서 스파크를위한 솔루션입니다. 널 (null)를 포함하는 데이터 행을 선택합니다. 당신은 데이터 집합의 데이터가있을 때, 당신이 할 :
여기에 자바에서 스파크를위한 솔루션입니다. 널 (null)를 포함하는 데이터 행을 선택합니다. 당신은 데이터 집합의 데이터가있을 때, 당신이 할 :
Dataset<Row> containingNulls = data.where(data.col("COLUMN_NAME").isNull())
널 (null)없이 데이터를 필터링하려면 당신이 할 :
Dataset<Row> withoutNulls = data.where(data.col("COLUMN_NAME").isNotNull())
종종 dataframes 대신 널 (null)의 우리는 ""와 같은 빈 문자열이 String 유형의 열이 포함됩니다. 우리가 아니라 데이터를 필터링하려면 :
Dataset<Row> withoutNullsAndEmpty = data.where(data.col("COLUMN_NAME").isNotNull().and(data.col("COLUMN_NAME").notEqual("")))
-
==============================
8.첫 번째 질문에 대해, 당신이 널 (null)를 필터링하는 정확하고 따라서 수는 0입니다.
첫 번째 질문에 대해, 당신이 널 (null)를 필터링하는 정확하고 따라서 수는 0입니다.
사용 아래와 같은 두 번째 교체 :
val options = Map("path" -> "...\\ex.csv", "header" -> "true") val dfNull = spark.sqlContext.load("com.databricks.spark.csv", options) scala> dfNull.show +----------+----------+-------+--------+----------+-----------+---------+ | user_id| event_id|invited|day_diff|interested|event_owner|friend_id| +----------+----------+-------+--------+----------+-----------+---------+ | 4236494| 110357109| 0| -1| 0| 937597069| null| | 78065188| 498404626| 0| 0| 0| 2904922087| null| | 282487230|2520855981| 0| 28| 0| 3749735525| null| | 335269852|1641491432| 0| 2| 0| 1490350911| null| | 437050836|1238456614| 0| 2| 0| 991277599| null| | 447244169|2095085551| 0| -1| 0| 1579858878| a| | 516353916|1076364848| 0| 3| 1| 3597645735| b| | 528218683|1151525474| 0| 1| 0| 3433080956| c| | 531967718|3632072502| 0| 1| 0| 3863085861| null| | 627948360|2823119321| 0| 0| 0| 4092665803| null| | 811791433|3513954032| 0| 2| 0| 415464198| null| | 830686203| 99027353| 0| 0| 0| 3549822604| null| |1008893291|1115453150| 0| 2| 0| 2245155244| null| |1239364869|2824096896| 0| 2| 1| 2579294650| d| |1287950172|1076364848| 0| 0| 0| 3597645735| null| |1345896548|2658555390| 0| 1| 0| 2025118823| null| |1354205322|2564682277| 0| 3| 0| 2563033185| null| |1408344828|1255629030| 0| -1| 1| 804901063| null| |1452633375|1334001859| 0| 4| 0| 1488588320| null| |1625052108|3297535757| 0| 3| 0| 1972598895| null| +----------+----------+-------+--------+----------+-----------+---------+ dfNull.withColumn("friend_idTmp", when($"friend_id".isNull, "1").otherwise("0")).drop($"friend_id").withColumnRenamed("friend_idTmp", "friend_id").show +----------+----------+-------+--------+----------+-----------+---------+ | user_id| event_id|invited|day_diff|interested|event_owner|friend_id| +----------+----------+-------+--------+----------+-----------+---------+ | 4236494| 110357109| 0| -1| 0| 937597069| 1| | 78065188| 498404626| 0| 0| 0| 2904922087| 1| | 282487230|2520855981| 0| 28| 0| 3749735525| 1| | 335269852|1641491432| 0| 2| 0| 1490350911| 1| | 437050836|1238456614| 0| 2| 0| 991277599| 1| | 447244169|2095085551| 0| -1| 0| 1579858878| 0| | 516353916|1076364848| 0| 3| 1| 3597645735| 0| | 528218683|1151525474| 0| 1| 0| 3433080956| 0| | 531967718|3632072502| 0| 1| 0| 3863085861| 1| | 627948360|2823119321| 0| 0| 0| 4092665803| 1| | 811791433|3513954032| 0| 2| 0| 415464198| 1| | 830686203| 99027353| 0| 0| 0| 3549822604| 1| |1008893291|1115453150| 0| 2| 0| 2245155244| 1| |1239364869|2824096896| 0| 2| 1| 2579294650| 0| |1287950172|1076364848| 0| 0| 0| 3597645735| 1| |1345896548|2658555390| 0| 1| 0| 2025118823| 1| |1354205322|2564682277| 0| 3| 0| 2563033185| 1| |1408344828|1255629030| 0| -1| 1| 804901063| 1| |1452633375|1334001859| 0| 4| 0| 1488588320| 1| |1625052108|3297535757| 0| 3| 0| 1972598895| 1| +----------+----------+-------+--------+----------+-----------+---------+
-
==============================
9.내 질문을 해결하기 위해 다음 코드를 사용합니다. 효과가있다. 그러나 우리 모두 알다시피, 나는 그것을 해결하기 위해 국가의 마일을 주위에 작동합니다. 그래서, 그것을위한 지름길이있다? 감사
내 질문을 해결하기 위해 다음 코드를 사용합니다. 효과가있다. 그러나 우리 모두 알다시피, 나는 그것을 해결하기 위해 국가의 마일을 주위에 작동합니다. 그래서, 그것을위한 지름길이있다? 감사
def filter_null(field : Any) : Int = field match { case null => 0 case _ => 1 } val test = train_event_join.join( user_friends_pair, train_event_join("user_id") === user_friends_pair("user_id") && train_event_join("event_owner") === user_friends_pair("friend_id"), "left" ).select( train_event_join("user_id"), train_event_join("event_id"), train_event_join("invited"), train_event_join("day_diff"), train_event_join("interested"), train_event_join("event_owner"), user_friends_pair("friend_id") ).rdd.map{ line => ( line(0).toString.toLong, line(1).toString.toLong, line(2).toString.toLong, line(3).toString.toLong, line(4).toString.toLong, line(5).toString.toLong, filter_null(line(6)) ) }.toDF("user_id", "event_id", "invited", "day_diff", "interested", "event_owner", "creator_is_friend")
from https://stackoverflow.com/questions/39727742/how-to-filter-out-a-null-value-from-spark-dataframe by cc-by-sa and MIT license
'SCALA' 카테고리의 다른 글
[SCALA] 스칼라에서 memoize하는 일반적인 방법이 있나요? (0) | 2019.11.11 |
---|---|
[SCALA] 어떻게를 java.util.List에 scala.List를 변환하는? (0) | 2019.11.11 |
[SCALA] 어떻게 스파크 SQL에서 내림차순으로 열을 기준으로 정렬하려면? (0) | 2019.11.11 |
[SCALA] Build.scala, %와 의미 %% 문자 (0) | 2019.11.11 |
[SCALA] 구문 분석 CSV 파일을 사용 스칼라 파서 콤비 (0) | 2019.11.11 |