web-dev-qa-db-fra.com

Créer un histogramme avec la colonne Spark DataFrame

J'essaie de faire un histogramme avec une colonne à partir d'un cadre de données qui ressemble

DataFrame[C0: int, C1: int, ...]

Si je devais faire un histogramme avec la colonne C1, que devrais-je faire?

Certaines choses que j'ai essayées sont

df.groupBy("C1").count().histogram()
df.C1.countByValue()

Qui ne fonctionnent pas à cause de la discordance dans les types de données. 

5
user2857014

Vous pouvez utiliser histogram_numeric Hive UDAF:

import random

random.seed(323)

sqlContext = HiveContext(sc)
n = 3  # Number of buckets
df = sqlContext.createDataFrame(
    sc.parallelize(enumerate(random.random() for _ in range(1000))),
   ["id", "v"]
)

hists = df.selectExpr("histogram_numeric({0}, {1})".format("v", n))

hists.show(1, False)
## +------------------------------------------------------------------------------------+
## |histogram_numeric(v,3)                                                              |
## +------------------------------------------------------------------------------------+
## |[[0.2124888140177466,415.0], [0.5918851340384337,330.0], [0.8890271451209697,255.0]]|
## +------------------------------------------------------------------------------------+

Vous pouvez également extraire la colonne d’intérêt et utiliser la méthode histogram sur RDD:

df.select("v").rdd.flatMap(lambda x: x).histogram(n)
## ([0.002028109534323752,
##  0.33410233677189705,
##  0.6661765640094703,
##  0.9982507912470436],
## [327, 326, 347])
12
zero323

Ce qui a fonctionné pour moi, c'est 

df.groupBy("C1").count().rdd.values().histogram()

Je dois convertir en RDD car j'ai trouvé la méthode histogram dans la classe pyspark.RDD mais pas dans le module spark.SQL

5
lanenok

Le paquet pyspark_dist_explore mentionné par @Chris van den Berg est plutôt sympathique. Si vous préférez ne pas ajouter de dépendance supplémentaire, vous pouvez utiliser ce bit de code pour tracer un histogramme simple.

import matplotlib.pyplot as plt
# Show histogram of the 'C1' column
bins, counts = df.select('C1').rdd.flatMap(lambda x: x).histogram(20)

# This is a bit awkward but I believe this is the correct way to do it 
plt.hist(bins[:-1], bins=bins, weights=counts)
4
Briford Wylie

Supposons que vos valeurs dans C1 sont comprises entre 1 et 1 000 et que vous souhaitez obtenir un histogramme de 10 bacs. Vous pouvez faire quelque chose comme: Df.withColumn ("bacs", df.C1/100) .groupBy ("bacs"). Count () Si votre binning est plus complexe, vous pouvez créer une UDF pour cela (et au pire, vous devrez peut-être analyser la colonne en premier, par exemple en utilisant decrire ou par une autre méthode).

2
Assaf Mendelson

Si vous voulez tracer l'histogramme, vous pouvez utiliser le paquet pyspark_dist_explore :

fig, ax = plt.subplots()
hist(ax, df.groupBy("C1").count().select("count"))

Si vous souhaitez obtenir les données d'un DataFrame pandas, vous pouvez utiliser:

pandas_df = pandas_histogram(df.groupBy("C1").count().select("count"))
1
Chris van den Berg