Je suis novice à PySpark.
J'essaie d'effectuer une opération GroupBy pour obtenir le nombre agrégé. Mais je ne suis pas en mesure d'effectuer un groupBy en fonction de la fréquence temporelle. Je dois effectuer "groupBy" en utilisant les champs "CAPTUREDTIME, NODE, CHANNEL, LOCATION, TACK". Mais dans ce groupBy, je devrais grouper en fonction de «horaire», «quotidien», «hebdomadaire», «mensuel» en utilisant le champ «CAPTUREDTIME».
Veuillez trouver les exemples de données ci-dessous.
-----------------+------+------+--------+----------+--------------
|CAPTUREDTIME| NODE| CHANNEL | LOCATION| TACK
+-----------------+------+------+--------+----------+-------------
|20-05-09 03:06:21| PUSC_RES| SIMPLEX| NORTH_AL| UE220034
|20-05-09 04:33:04| PUSC_RES| SIMPLEX| SOUTH_AL| UE220034
|20-05-09 12:04:52| TESC_RES| SIMPLEX| NORTH_AL| UE220057
|20-05-10 04:24:09| TESC_RES| SIMPLEX| NORTH_AL| UE220057
|20-05-10 04:33:04| PUSC_RES| SIMPLEX| SOUTH_AL| UE220034
|20-04-09 10:57:48| TESC_RES| SIMPLEX| NORTH_AL| UE220057
|20-04-09 12:12:26| TESC_RES| SIMPLEX| NORTH_AL| UE220057
|20-04-09 03:26:33| PUSC_RES| SIMPLEX| NORTH_AL| UE220071
+-----------------+------+------+--------+----------+-------------
J'ai utilisé le code pyspark ci-dessous
df = df.groupby("CAPTUREDTIME", "NODE", "CHANNEL", "LOCATION", "TACK").agg(
func.count("TACK").alias("count")
)
Comment puis-je étendre le code ci-dessus au groupe sur «horaire», «quotidien», «hebdomadaire», «mensuel»?
J'ai besoin de la sortie au format ci-dessous (j'ai partagé un exemple de sortie):
HORAIRE:
| CAPTUREDTIME | NODE | CHANNEL | LIEU | TACK | COMPTER
| 20-05-09 03: 00: 00 | PUSC_RES | SIMPLEX | NORTH_AL | UE220034 | 2
| 20-05-09 04: 00: 00 | PUSC_RES | SIMPLEX | SOUTH_AL | UE220034 | 2
DU QUOTIDIEN :
| CAPTUREDTIME | NODE | CHANNEL | LIEU | TACK | COMPTER
| 20-05-09 00: 00: 00 | PUSC_RES | SIMPLEX | NORTH_AL | UE220034 | 1
| 20-05-09 00: 00: 00 | PUSC_RES | SIMPLEX | SOUTH_AL | UE220034 | 2
| 20-05-09 00: 00: 00 | TESC_RES | SIMPLEX | NORTH_AL | UE220057 | 3
HEBDOMADAIRE :
| CAPTUREDTIME | NODE | CHANNEL | LIEU | TACK | COMPTER
| 20-05-09 00: 00: 00 | PUSC_RES | SIMPLEX | NORTH_AL | UE220034 | 1
MENSUEL :
| CAPTUREDTIME | NODE | CHANNEL | LIEU | TACK | COMPTER
| 20-05-09 00: 00: 00 | PUSC_RES | SIMPLEX | NORTH_AL | UE220034 | 1
Vous avez deux façons de répondre à votre problème, soit vous convertissez vos horodatages avec la granularité de date que vous souhaitez regrouper, soit (comme vous l'avez dit dans les commentaires) vous utilisez la fonction de fenêtre SQL pour regrouper par intervalle que vous souhaitez.
Sachez simplement que l'agrégation mensuelle n'est pas possible via la fonction SQL de fenêtre dans Spark.
Ici vous pouvez voir le code, les trois premiers exemples utilisent la fonction SQL de fenêtre et le dernier exemple convertit l'horodatage tous les mois, puis le groupe par colonnes.
df = spark.createDataFrame(
[
("20-05-09 03:06:21", "PUSC_RES", "SIMPLEX", "NORTH_AL", "UE220034"),
("20-05-09 04:33:04", "PUSC_RES", "SIMPLEX", "SOUTH_AL", "UE220034"),
("20-05-09 12:04:52", "TESC_RES", "SIMPLEX", "NORTH_AL", "UE220057"),
("20-05-10 04:24:09", "TESC_RES", "SIMPLEX", "NORTH_AL", "UE220057"),
("20-05-10 04:33:04", "PUSC_RES", "SIMPLEX", "SOUTH_AL", "UE220034"),
("20-04-09 10:57:48", "TESC_RES", "SIMPLEX", "NORTH_AL", "UE220057"),
("20-04-09 12:12:26", "TESC_RES", "SIMPLEX", "NORTH_AL", "UE220057"),
("20-04-09 03:26:33", "PUSC_RES", "SIMPLEX", "NORTH_AL", "UE220071")
],
['CAPTUREDTIME', 'NODE', 'CHANNEL', 'LOCATION', 'TACK']
)
from pyspark.sql.functions import col, count, date_format, date_sub, date_trunc, month, next_day, to_timestamp, weekofyear, window, year
Je garde toujours la logique de la fenêtre juste pour celui-ci, afin que nous puissions référencer pour tout le monde toutes les possibilités dans Spark. Je sélectionne seulement le début de la fenêtre à la fin avant d'afficher le dataframe.
hourly = (
df
.withColumn("captured_time", to_timestamp(col('CAPTUREDTIME'), 'yy-MM-dd HH:mm:ss'))
.groupBy(window(col("captured_time"), "1 hour").alias("captured_time"), "NODE", "CHANNEL", "LOCATION", "TACK")
.agg(count("*"))
.withColumn("captured_time_hour", col("captured_time.start"))
.drop("captured_time")
)
hourly.sort("captured_time_hour").show(100, False)
Grâce à la date_truncfonction, je peux tronquer l'horodatage uniquement en considérant le jour
daily = (
df
.withColumn("captured_time", to_timestamp(col('CAPTUREDTIME'), 'yy-MM-dd HH:mm:ss'))
.withColumn("captured_time_day", date_trunc("day", col("captured_time")))
.groupBy("captured_time_day", "NODE", "CHANNEL", "LOCATION", "TACK")
.agg(count("*"))
)
daily.sort("captured_time_day").show(100, False)
Celui-ci est un peu plus délicat. J'utilise d'abord, une next_dayfonction avec lundi. S'il vous plaît, si vous considérez dimanche comme le début de la semaine, mettez à jour ce code en fonction de celui-ci, mais je considère le lundi comme le début de la semaine (cela dépend des dialectes SQL que je crois et des régions)
Ensuite, nous pouvons également ajouter une weekofyearfonction pour récupérer le numéro de semaine comme vous le souhaitez
weekly = (
df
.withColumn("captured_time", to_timestamp(col('CAPTUREDTIME'), 'yy-MM-dd HH:mm:ss'))
.withColumn("start_day", date_sub(next_day(col("captured_time"), "monday"), 7))
.groupBy("start_day", "NODE", "CHANNEL", "LOCATION", "TACK")
.agg(count("*"))
.withColumn("start_day", to_timestamp(col("start_day")))
.withColumn("week_of_year", weekofyear(col("start_day")))
)
weekly.sort("start_day").show(100, False)
Nous formalisons simplement l'horodatage sous forme de date, puis nous le convertissons en horodatage. Ceci est juste fait pour montrer une autre façon de le faire. Nous pourrions simplement tronquer l'horodatage comme cas d'utilisation quotidien. Je montre également deux façons d'extraire le nom du mois et l'abréviation. Prenez simplement soin de votre version de Spark car elle est testée dans Spark 3.0.0
monthly = (
df
.withColumn("captured_time", to_timestamp(col('CAPTUREDTIME'), 'yy-MM-dd HH:mm:ss'))
.withColumn("captured_time_month", date_format(col('captured_time'), '1/M/yyyy'))
.groupBy(col("captured_time_month"), "NODE", "CHANNEL", "LOCATION", "TACK")
.agg(count("*").alias("Count TACK"))
.withColumn("captured_time_month", to_timestamp(col("captured_time_month"), '1/M/yyyy'))
.withColumn("month", month(col("captured_time_month")))
.withColumn("month_abbr", date_format(col("captured_time_month"),'MMM'))
.withColumn("full_month_name", date_format(col("captured_time_month"),'MMMM'))
)
monthly.sort("captured_time_month").show(100, False)
Ciao!
Spark fournit une bibliothèque relativement riche pour la manipulation de dates. La réponse à votre question est une combinaison d'extraction de parties de date et de formatage de date pour l'affichage.
J'ai recréé vos données comme suit:
val capturesRaw = spark.read
.option("ignoreLeadingWhiteSpace", "true")
.option("ignoreTrailingWhiteSpace", "true")
.option("delimiter", "|")
.option("header", "true")
.csv(spark.sparkContext.parallelize("""
CAPTUREDTIME| NODE| CHANNEL | LOCATION| TACK
20-05-09 03:06:21| PUSC_RES| SIMPLEX| NORTH_AL| UE220034
20-05-09 04:33:04| PUSC_RES| SIMPLEX| SOUTH_AL| UE220034
20-05-09 12:04:52| TESC_RES| SIMPLEX| NORTH_AL| UE220057
20-05-10 04:24:09| TESC_RES| SIMPLEX| NORTH_AL| UE220057
20-05-10 04:33:04| PUSC_RES| SIMPLEX| SOUTH_AL| UE220034
20-04-09 10:57:48| TESC_RES| SIMPLEX| NORTH_AL| UE220057
20-04-09 12:12:26| TESC_RES| SIMPLEX| NORTH_AL| UE220057
20-04-09 03:26:33| PUSC_RES| SIMPLEX| NORTH_AL| UE220071"""
.split("\n")).toDS)
Remarque: j'utilise Scala, mais la différence dans le code est si petite que j'espère que vous la trouverez compréhensible. Je crois que valle début est la seule différence en fait.
Je suppose que les deux premiers chiffres représentent une année à deux chiffres? Pour continuer, nous devons nous assurer que le temps capturé est un horodatage. Je préfère utiliser SQL pour manipuler les dataframes, car je le trouve plus lisible.
spark.sql("""select to_timestamp('20' || capturedtime) capturedtime, NODE, CHANNEL,
LOCATION, TACK from captures_raw""")
.createOrReplaceTempView("captures_raw")
La même chose peut être faite directement sur le dataframe, si vous préférez
capturesRaw.withColumn("capturedtimestamp",
to_timestamp(col("capturedtime"), "yy-MM-dd hh:mm:ss"))
À ce stade, nous pouvons créer les champs que vous avez demandés:
spark.sql("""select capturedtime,
month(capturedtime) cap_month,
weekofyear(capturedtime) cap_week,
day(capturedtime) cap_day,
hour(capturedtime) cap_hr, NODE, CHANNEL, LOCATION, TACK
from captures_raw""").createOrReplaceTempView("captures")
Une fois les champs créés, nous sommes prêts à répondre à votre question. Pour agréger par mois uniquement (sans reste de l'horodatage), par exemple, procédez comme suit:
spark.sql("""select date_format(capturedtime, "yyyy-MM") year_month, cap_month,
cap_week, cap_day, cap_hr, count(*) count
from captures
group by 1,2,3,4,5""").show
Quels retours
+----------+---------+--------+-------+------+-----+
|year_month|cap_month|cap_week|cap_day|cap_hr|count|
+----------+---------+--------+-------+------+-----+
| 2020-04| 4| 15| 9| 3| 1|
| 2020-04| 4| 15| 9| 10| 1|
| 2020-05| 5| 19| 9| 4| 1|
| 2020-05| 5| 19| 9| 12| 1|
| 2020-04| 4| 15| 9| 12| 1|
| 2020-05| 5| 19| 9| 3| 1|
| 2020-05| 5| 19| 10| 4| 2|
+----------+---------+--------+-------+------+-----+
Un résumé quotidien peut être produit comme suit:
spark.sql("""select date_format(capturedtime, "yyyy-MM-dd") captured_date,
cap_day, cap_hr, count(*) count
from captures
group by 1,2,3""").show
+-------------+-------+------+-----+
|captured_date|cap_day|cap_hr|count|
+-------------+-------+------+-----+
| 2020-05-10| 10| 4| 2|
| 2020-04-09| 9| 12| 1|
| 2020-05-09| 9| 4| 1|
| 2020-05-09| 9| 12| 1|
| 2020-04-09| 9| 3| 1|
| 2020-04-09| 9| 10| 1|
| 2020-05-09| 9| 3| 1|
+-------------+-------+------+-----+
Jana Duggar a été ouverte sur sa recherche de l'amour. Voici tout ce qu'elle a dit sur le sujet et sa fenêtre de mariage de cinq ans.
La star d'Outlander, Sam Heughan, a récemment révélé ce qu'il retirera du tournage pour se souvenir de Jamie Fraser, le rôle qui a fait de lui une star.
"She Loves You" a été écrite en une heure, enregistrée en une journée, et a été la chanson des Beatles avec l'une de leurs meilleures performances de leur carrière.
Dolly Parton et sa grand-mère Bessie avaient une relation spéciale. Grand-mère Parton était très malade, mais cela n'a pas empêché Dolly de lui faire des farces.
Vous pensez peut-être que le chêne ou le noyer sont résistants, mais en matière de bois les plus durs au monde, ils sont loin derrière.
L'océan regorge de beauté, mais il abrite aussi certaines des créatures marines les plus terrifiantes de la planète. Nombre de ces animaux vivent dans les profondeurs obscures et sous haute pression des abysses.
Que vous affrontiez des créatures hostiles ou vous prépariez pour des affrontements PvP, connaître les meilleurs enchantements d'épée dans Minecraft peut vous donner un avantage considérable. Enchanter vos épées vous permet d'infliger plus de dégâts, d'augmenter le butin des créatures et d'accroître leur durabilité.
Quand on parle de pays socialistes, on imagine souvent un contrôle total de l'État et l'absence de propriété privée. Mais en réalité, les économies socialistes sont très diverses.
« Enfants » laisse tomber un caméo de grand nom et des nouvelles dévastatrices
Ce RAV4 est déclaré en excellent état et est prêt pour un jeu de chaises musicales.
Des images de drones ont montré des pompiers semblant lutter pour éteindre l'incendie.
Eyes of Wakanda est directement lié au MCU, ainsi que des mises à jour sur X-Men '97, What If..., Daredevil, et plus encore.
Ava Gardner a été mariée à Mickey Rooney et Frank Sintra, et a fréquenté plusieurs autres stars d'Hollywood. Voici un aperçu de l'histoire amoureuse d'Ava Gardner.
John Cleese a épousé sa femme, Jennifer Wade, en 2012. Voici tout ce qu'il faut savoir sur la femme de John Cleese, Jennifer Wade.
Craig Melvin a épousé la présentatrice sportive Lindsay Czarniak en 2011. Voici tout ce qu'il faut savoir sur la femme de Craig Melvin.
Maggie Gyllenhaal et Peter Sarsgaard se sont mariés en 2009 et partagent deux filles ensemble. Voici une chronologie complète de leur relation.
Ça me frappe tout à coup, comme c'est si souvent le cas C'est à nouveau le milieu du chemin <Non, pas celui du Pacifique, toi marron, celui du carnaval> Chaque gros titre fort… ..
En 2022, avec la sortie de GPT-3, la compétence en écriture semble devenir moins importante. Avec l'IA, les personnes ayant une mauvaise écriture peuvent également générer du personnel de qualité.
Dans le monde rapide et compétitif d'aujourd'hui, la carrière d'une personne joue un rôle important dans la croissance personnelle, la stabilité financière et la satisfaction globale de la vie. Cependant, de nombreuses personnes se retrouvent prises dans un cycle incessant de stagnation et d'insatisfaction, dépérissant progressivement dans leur vie professionnelle.
La semaine dernière, j'ai remarqué un communiqué de presse, envoyé via PressGazette (un site Web d'information britannique). L'article annonçait qu'Acast, la société d'hébergement et de publicité de podcasts de Scandi, dirigerait un consortium d'éditeurs "probablement les plus influents" du podcasting.