복붙노트

[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. ==============================

    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. ==============================

    2.또는 df.filter처럼 ($ .isNotNull "friend_id")

    또는 df.filter처럼 ($ .isNotNull "friend_id")

  3. ==============================

    3.

    df.where(df.col("friend_id").isNull)
    
  4. ==============================

    4.나를 위해 좋은 솔루션에 null 값으로 행을 드롭했다 :

    나를 위해 좋은 솔루션에 null 값으로 행을 드롭했다 :

    데이터 집합 <행> = 필터링 df.filter (행 => row.anyNull!);

    경우 하나가 다른 경우 관심, 그냥 row.anyNull를 호출합니다. (스파크 2.1.0 사용하는 Java API)

  5. ==============================

    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. ==============================

    6.마이클 Kopaniov에서, 작품 아래 힌트에서

    마이클 Kopaniov에서, 작품 아래 힌트에서

    df.where(df("id").isNotNull).show
    
  7. ==============================

    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. ==============================

    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. ==============================

    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")
    
  10. from https://stackoverflow.com/questions/39727742/how-to-filter-out-a-null-value-from-spark-dataframe by cc-by-sa and MIT license