2015-11-17 13 views
9

Witam Mam następujący problem:Sparksql filtrowanie (wybierając z którym klauzula) z wielu warunków

numeric.registerTempTable("numeric"). 

Wszystkie wartości, które chcę, aby filtrować na dosłowne ciągi zerowe i nie N/A lub wartości NULL.

Próbowałem te trzy opcje:

  1. numeric_filtered = numeric.filter(numeric['LOW'] != 'null').filter(numeric['HIGH'] != 'null').filter(numeric['NORMAL'] != 'null')

  2. numeric_filtered = numeric.filter(numeric['LOW'] != 'null' AND numeric['HIGH'] != 'null' AND numeric['NORMAL'] != 'null')

  3. sqlContext.sql("SELECT * from numeric WHERE LOW != 'null' AND HIGH != 'null' AND NORMAL != 'null'")

Niestety numeric_filtered jest zawsze pusty. Sprawdziłem i dane numeryczne mają dane, które powinny być filtrowane na podstawie tych warunków.

Oto niektóre przykładowe wartości:

Niska Wysoka Normalna

3,5 5,0 zerowy

2,0 14,0 zerowy

zerowa 38,0 zerowy

wartość null null null

1.0 null 4.0

Odpowiedz

17

Używasz logicznego spójnika (AND). Oznacza to, że wszystkie kolumny muszą być inne niż 'null', aby wiersz mógł zostać uwzględniony. Pozwala to zilustrować za pomocą filter wersji jako przykład:

numeric = sqlContext.createDataFrame([ 
    ('3.5,', '5.0', 'null'), ('2.0', '14.0', 'null'), ('null', '38.0', 'null'), 
    ('null', 'null', 'null'), ('1.0', 'null', '4.0')], 
    ('low', 'high', 'normal')) 

numeric_filtered_1 = numeric.where(numeric['LOW'] != 'null') 
numeric_filtered_1.show() 

## +----+----+------+ 
## | low|high|normal| 
## +----+----+------+ 
## |3.5,| 5.0| null| 
## | 2.0|14.0| null| 
## | 1.0|null| 4.0| 
## +----+----+------+ 

numeric_filtered_2 = numeric_filtered_1.where(
    numeric_filtered_1['NORMAL'] != 'null') 
numeric_filtered_2.show() 

## +---+----+------+ 
## |low|high|normal| 
## +---+----+------+ 
## |1.0|null| 4.0| 
## +---+----+------+ 

numeric_filtered_3 = numeric_filtered_2.where(
    numeric_filtered_2['HIGH'] != 'null') 
numeric_filtered_3.show() 

## +---+----+------+ 
## |low|high|normal| 
## +---+----+------+ 
## +---+----+------+ 

Wszystkie pozostałe metody próbowałem śledzić dokładnie ten sam schemat. To, czego potrzebujesz, to logiczna alternatywa (OR).

from pyspark.sql.functions import col 

numeric_filtered = df.where(
    (col('LOW') != 'null') | 
    (col('NORMAL') != 'null') | 
    (col('HIGH') != 'null')) 
numeric_filtered.show() 

## +----+----+------+ 
## | low|high|normal| 
## +----+----+------+ 
## |3.5,| 5.0| null| 
## | 2.0|14.0| null| 
## |null|38.0| null| 
## | 1.0|null| 4.0| 
## +----+----+------+ 

lub z surowego SQL:

numeric.registerTempTable("numeric") 
sqlContext.sql("""SELECT * FROM numeric 
    WHERE low != 'null' OR normal != 'null' OR high != 'null'""" 
).show() 

## +----+----+------+ 
## | low|high|normal| 
## +----+----+------+ 
## |3.5,| 5.0| null| 
## | 2.0|14.0| null| 
## |null|38.0| null| 
## | 1.0|null| 4.0| 
## +----+----+------+ 

Patrz także: Pyspark: multiple conditions in when clause

+0

Dzięki! To bardzo pomogło. Ważną rzeczą jest zawarcie indywidualnych warunków w parantach ** (** col ('foo') == 'bar' **) ** –