web-dev-qa-db-fra.com

Fonction "entre" de pyspark: la recherche de plage sur les horodatages n'est pas inclusive

la fonction "entre" de pyspark n'est pas inclusive pour l'entrée d'horodatage.

Par exemple, si nous voulons toutes les lignes entre deux dates, disons '2017-04-13' et '2017-04-14', alors il effectue une recherche "exclusive" lorsque les dates sont passées sous forme de chaînes. c'est-à-dire qu'il omet les champs '2017-04-14 00:00:00'

Cependant, le document semble indiquer qu'il est inclus (pas de référence sur l'horodatage cependant)

Bien sûr, une façon consiste à ajouter une microseconde à partir de la limite supérieure et à la passer à la fonction. Cependant, ce n'est pas une bonne solution. Une façon propre de faire une recherche inclusive?

Exemple:

import pandas as pd
from pyspark.sql import functions as F
... sql_context creation ...
test_pd=pd.DataFrame([{"start":'2017-04-13 12:00:00', "value":1.0},{"start":'2017-04-14 00:00:00', "value":1.1}])
test_df = sql_context.createDataFrame(test_pd).withColumn("start", F.col("start").cast('timestamp'))
test_df.show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+

test_df.filter(F.col("start").between('2017-04-13','2017-04-14')).show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
+--------------------+-----+
10
Vinay Kolar

J'ai trouvé la réponse. La fonction "entre" de pyspark est incohérente dans la gestion des entrées d'horodatage.

  1. Si vous fournissez l'entrée au format chaîne sans temps, il effectue une recherche exclusive (pas ce que nous attendons de la documentation liée ci-dessus).
  2. Si vous fournissez l'entrée en tant qu'objet datetime ou avec l'heure exacte (par exemple, `` 2017-04-14 00:00:00 '', alors elle effectue une recherche inclusive.

Pour l'exemple ci-dessus, voici la sortie pour la recherche exclusive (utilisez pd.to_datetime):

test_df.filter(F.col("start").between(pd.to_datetime('2017-04-13'),pd.to_datetime('2017-04-14'))).show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+

De même, si nous fournissons la date ET l'heure au format chaîne, il semble effectuer une recherche inclusive:

test_df.filter(F.col("start").between('2017-04-13 12:00:00','2017-04-14 00:00:00')).show()

+--------------------+-----+
|               start|value|
+--------------------+-----+
|2017-04-13 12:00:...|  1.0|
|2017-04-14 00:00:...|  1.1|
+--------------------+-----+
5
Vinay Kolar