2016-12-20 2 views
1

У меня есть и пХт DataFrame и 1 хт DataFrameСравнивая DataFrames, чтобы получить логические столбцы

df1=sc.parallelize([('a1',.5,.27),('a2',.15,.40),('a3',.7,.05)]).toDF(['id1','x1', 'x2']) 

+---+----+----+ 
|id1| x1| x2| 
+---+----+----+ 
| a1| 0.5|0.27| 
| a2|0.15| 0.4| 
| a3| 0.7|0.05| 
+---+----+----+ 

df2=sc.parallelize([(.4,.3)]).toDF(['w1','w2']) 


+---+---+ 
| w1| w2| 
+---+---+ 
|0.4|0.3| 
+---+---+ 

Я хотел бы выполнить булеву операцию сравнения столбца x1 в df1 колонке w1 в df2 и колонки x2 в df2 в столбец w2 в df2. Я хотел бы, чтобы результат возвращал DataFrame, в котором первый столбец «id1» в df1.

Я хочу, чтобы мой результат, чтобы выглядеть следующим образом

+---+---+---+ 
|id1| x1| x2| 
+---+---+---+ 
| a1| 1| 0| 
| a2| 0| 1| 
| a3| 1| 0| 
+---+---+---+ 

Все, что я прямо сейчас

rd=df1.rdd 
rd_list=df2.rdd.collect() 


def function_1(x): 
    bool_1=int(x[1]>rd_list[0][0]) 
    bool_2=int(x[2]>rd_list[0][1]) 
    return (x[0],bool_1,bool_2) 
rd.map(function_1).toDF().show() 

+---+---+---+ 
|id1| x1| x2| 
+---+---+---+ 
| a1| 1| 0| 
| a2| 0| 1| 
| a3| 1| 0| 
+---+---+---+ 

это заставляет меня мой результат, но должно быть лучше.

ответ

2

Вы можете сравнить с литералов (с использованием одного кадра данных строка не имеет особого смысла):

from pyspark.sql.functions import col 

w1, w2 = df2.first() 

df1.select(
    "id1", 
    (col("x1") > w1).cast("integer"), 
    (col("x2") > w2).cast("integer") 
).toDF("id1", "w1", "w2") 

или применить перекрестный продукт и select:

from pyspark.sql.functions import broadcast 

df1.crossJoin(broadcast(df2)).select(
    "id1", 
    (col("x1") > col("w1")).cast("integer"), 
    (col("x2") > col("w2")).cast("integer") 
).toDF("id1", "x1", "x2") 

Если вы используете Спарк 2.0 или ранее join, а не crossJoin, должны иметь такой же эффект в сочетании с broadcast.