web-dev-qa-db-fra.com

Filtrage Sparksql (sélection avec clause where) avec plusieurs conditions

Salut, j'ai le problème suivant:

numeric.registerTempTable("numeric"). 

Toutes les valeurs sur lesquelles je veux filtrer sont des chaînes nulles littérales et non des valeurs N/A ou Null.

J'ai essayé ces trois options:

  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'")

Malheureusement, numeric_filtered est toujours vide. J'ai vérifié et le numérique contient des données qui doivent être filtrées en fonction de ces conditions.

Voici quelques exemples de valeurs:

Faible Élevé Normal

3,5 5,0 null

2.0 14.0 null

null 38.0 null

null null null

1.0 null 4.0

11
user3803714

Vous utilisez la conjonction logique (ET). Cela signifie que toutes les colonnes doivent être différentes de 'null' pour que la ligne soit incluse. Permet d'illustrer que l'utilisation de la version filter comme exemple:

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|
## +---+----+------+
## +---+----+------+

Toutes les autres méthodes que vous avez essayées suivent exactement le même schéma. Ce dont vous avez besoin ici, c'est d'une disjonction logique (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|
## +----+----+------+

ou avec du SQL brut:

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|
## +----+----+------+

Voir aussi: Pyspark: plusieurs conditions dans la clause when

21
zero323