2017-05-03 6 views
0

neuen Datenrahmen zu schaffen, hatte ich einen dict, wie:wie mit dict

cMap = {"k1" : "v1", "k2" : "v1", "k3" : "v2", "k4" : "v2"} 

und ein Datenrahmen A, wie:

+---+ 
|key| 
+---- 
| k1| 
| k2| 
| k3| 
| k4| 
+---+ 

die DataFame oben mit Code zu erstellen:

data = [('k1'), 
    ('k2'), 
    ('k3'), 
    ('k4')] 
A = spark.createDataFrame(data, ['key']) 

Ich möchte den neuen DataFrame erhalten, wie:

+---+----------+----------+ 
|key| v1  | v2 | 
+---+----------+----------+ 
| k1|ture  |false  | 
| k2|ture  |false  | 
| k3|false  |ture  | 
| k4|false  |ture  | 
+---+----------+----------+ 

Ich möchte ein paar Vorschläge bekommen, danke!

Antwort

0

Vielen Dank allen für einige Vorschläge, ich herausgefunden das andere Art und Weise mein Problem mit Dreh zu lösen, ist der Code:

cMap = {"k1" : "v1", "k2" : "v1", "k3" : "v2", "k4" : "v2"} 
a_cMap = [(k,)+(v,) for k,v in cMap.items()] 
data = spark.createDataFrame(a_cMap, ['key','val']) 

from pyspark.sql.functions import count 
data = data.groupBy('key').pivot('val').agg(count('val')) 
data.show() 

+---+----+----+ 
|key| v1| v2| 
+---+----+----+ 
| k2| 1|null| 
| k4|null| 1| 
| k1| 1|null| 
| k3|null| 1| 
+---+----+----+ 

data = data.na.fill(0) 
data.show() 

+---+---+---+ 
|key| v1| v2| 
+---+---+---+ 
| k2| 1| 0| 
| k4| 0| 1| 
| k1| 1| 0| 
| k3| 0| 1| 
+---+---+---+ 

keys = spark.createDataFrame([('k1','2'),('k2','3'),('k3','4'),('k4','5'),('k5','6')], ["key",'temp']) 

newDF = keys.join(data,'key') 
newDF.show() 
+---+----+---+---+ 
|key|temp| v1| v2| 
+---+----+---+---+ 
| k2| 3| 1| 0| 
| k4| 5| 0| 1| 
| k1| 2| 1| 0| 
| k3| 4| 0| 1| 
+---+----+---+---+ 

Aber ich kann nicht 1 zu wahr, 0 zu false konvertieren.

3

Das Wörterbuch kann in einen Datenrahmen konvertiert und mit einem anderen verbunden werden. Mein Stück Code,

data = sc.parallelize([(k,)+(v,) for k,v in cMap.items()]).toDF(['key','val']) 
keys = sc.parallelize([('k1',),('k2',),('k3',),('k4',)]).toDF(["key"]) 
newDF = data.join(keys,'key').select("key",F.when(F.col("val") == "v1","True").otherwise("False").alias("v1"),F.when(F.col("val") == "v2","True").otherwise("False").alias("v2")) 

>>> newDF.show() 
+---+-----+-----+ 
|key| v1| v2| 
+---+-----+-----+ 
| k1| True|False| 
| k2| True|False| 
| k3|False| True| 
| k4|False| True| 
+---+-----+-----+ 

Wenn es mehr Werte gibt, können Sie die Klausel when als UDF codieren und verwenden.

+0

Eigentlich gibt es mehr Werte, können Sie mir sagen, wie man die UDF baut? –

1

Ich parallelize cMap.items() und prüfen, ob der Wert v1 oder v2 oder nicht entspricht. Dann verbindet zurück zu Datenrahmen A auf Spalte key

# example dataframe A 
df_A = spark.sparkContext.parallelize(['k1', 'k2', 'k3', 'k4']).map(lambda x: Row(**{'key': x})).toDF() 

cmap_rdd = spark.sparkContext.parallelize(cMap.items()) 
cmap_df = cmap_rdd.map(lambda x: Row(**dict([('key', x[0]), ('v1', x[1]=='v1'), ('v2', x[1]=='v2')]))).toDF() 

df_A.join(cmap_df, on='key').orderBy('key').show() 

Datenrahmen

+---+-----+-----+ 
|key| v1| v2| 
+---+-----+-----+ 
| k1| true|false| 
| k2| true|false| 
| k3|false| true| 
| k4|false| true| 
+---+-----+-----+ 
0

Ich wollte nur einen anderen und möglicherweise einfacheren Weg, um dies zu lösen beitragen.

In meinem Code konvertiere ich ein Diktat in einen Pandas Datenrahmen, was ich finde, ist viel einfacher. Dann konvertiere ich den Pandas-Datenrahmen direkt in Spark.

data = {'visitor': ['foo', 'bar', 'jelmer'], 
     'A': [0, 1, 0], 
     'B': [1, 0, 1], 
     'C': [1, 0, 0]} 

df = pd.DataFrame(data) 
ddf = spark.createDataFrame(df) 

Output: 
+---+---+---+-------+ 
| A| B| C|visitor| 
+---+---+---+-------+ 
| 0| 1| 1| foo| 
| 1| 0| 0| bar| 
| 0| 1| 0| jelmer| 
+---+---+---+-------+