2016-10-24 4 views
1

Ich habe einen Datenrahmen Objekt, das wie folgt aussieht:Scala relative Häufigkeit

+--+----+----+----+----+----+----+----+----+----+-----+ 
|id|bin1|bin2|bin3|bin4|bin5|bin6|bin7|bin8|bin9|bin10| 
+--+----+----+----+----+----+----+----+----+----+-----+ 
|a | 1|null|null|null|null| 1| 14| 91| 929| null| 
|c | 4| 2| 5| 82| 49| 176| 222| 439|null| null| 
|f | 1| 1|null|null| 2| 8| 226| 294| 2| null| 
|e |null| 1| 2|null| 4| 13| 19| 242| 752| 1| 
|y | 1| 1| 3| 9| 11| 17| 136| 664| 338| null| 
|e | 4| 2| 1| 8| 14| 169| 952| 431|null| null| 

Wie kann ich die absoluten Werte mit relativen Werten (Frequenz) ersetzen?

Edit: Nach der Transformation der Datenframe-Objekt für die erste Zeile sollte wie folgt aussehen:

+--+----+----+----+----+----+----+-----+------+-----+-----+ 
|id|bin1|bin2|bin3|bin4|bin5|bin6|bin7 |bin8 |bin9 |bin10| 
+--+----+----+----+----+----+----+-----+------+-----+-----+ 
|a | 0.0|null|null|null|null| 0.0| 0.01| 0.09| 0.90| null| 

Der Algorithmus jeden Wert einer Zelle durch die Summe der Reihe teilen sollte. Nach dieser Transformation ist die Summe einer Zeile immer 1.

Ich denke, ich kann es mit Karte erreichen, aber ich habe keine Ahnung, wie es geht.

+0

Es wäre hilfreich, wenn Sie, was die erwartete Ausgabe aussehen soll zeigen können. – Brian

+0

Vielen Dank für Ihren Kommentar. Ich habe meinen Beitrag bearbeitet und hoffe, es wird klarer. – cronoik

+0

Können Sie hinzufügen, was Sie bisher versucht haben? Und, ist das Hausaufgaben? – Jeremy

Antwort

1

Angenommen, Sie wollen die null s als 0s behandelt zu werden, hier ist eine Lösung:

scala> var df = Seq((1d,2d,Double.NaN),(Double.NaN, 3d,4d), (5d, Double.NaN, 6d)).toDF("a", "b", "c") 
df: org.apache.spark.sql.DataFrame = [a: double, b: double, c: double] 

scala> df.show 
+---+---+---+ 
| a| b| c| 
+---+---+---+ 
|1.0|2.0|NaN| 
|NaN|3.0|4.0| 
|5.0|NaN|6.0| 
+---+---+---+ 

scala> val cols = df.columns 
cols: Array[String] = Array(a, b, c) 

scala> import org.apache.spark.sql.DataFrameNaFunctions 

scala> df = df.na.fill(0d).withColumn("sum", cols.map(col).reduce(_ + _)) 
df: org.apache.spark.sql.DataFrame = [a: double, b: double, c: double, sum: double] 

scala> df.show 
+---+---+---+----+ 
| a| b| c| sum| 
+---+---+---+----+ 
|1.0|2.0|0.0| 3.0| 
|0.0|3.0|4.0| 7.0| 
|5.0|0.0|6.0|11.0| 
+---+---+---+----+ 


scala> cols.foreach(cName => df = df.withColumn(cName, df.col(cName)/df.col("sum"))) 

scala> df.drop("sum").show 
+-------------------+-------------------+------------------+ 
|     a|     b|     c| 
+-------------------+-------------------+------------------+ 
| 0.3333333333333333| 0.6666666666666666|    0.0| 
|    0.0|0.42857142857142855|0.5714285714285714| 
|0.45454545454545453|    0.0|0.5454545454545454| 
+-------------------+-------------------+------------------+ 
+0

Danke. Ihr Beispiel hat mir sehr geholfen. – cronoik