簡體   English   中英

Pyspark-根據來自不同數據框的值向數據框添加列

[英]Pyspark - add columns to dataframe based on values from different dataframe

我有兩個數據框。

AA = 

+---+----+---+-----+-----+
| id1|id2| nr|cell1|cell2|
+---+----+---+-----+-----+
|  1|   1|  0| ab2 | ac3 |
|  1|   1|  1| dg6 | jf2 |
|  2|   1|  1| 84d | kf6 |
|  2|   2|  1| 89m | k34 |
|  3|   1|  0| 5bd | nc4 |
+---+----+---+-----+-----+

第二個數據框BB ,如下所示:

BB =

+---+----+---+-----+
| a |   b|use|cell |
+---+----+---+-----+
|  1|   1|  x| ab2 |
|  1|   1|  a| dg6 |
|  2|   1|  b| 84d |
|  2|   2|  t| 89m |
|  3|   1|  d| 5bd |
+---+----+---+-----+

其中,在BB ,細胞部分,我有可以出現在所有可能的細胞AA cell1cell2部分( cell1 - cell2是一個間隔)。

我想向BB添加兩個列, val1val2 條件如下。

val1 has 1 values when:
             id1 == id2 (in AA) , 
         and cell (in B) == cell1 or cell2 (in AA)
         and nr = 1 in AA.

and 0 otherwise. 

另一列根據以下內容構造:

val 2 has 1 values when:
           id1 != id2 in (AA)
      and  cell (in B) == cell1 or cell 2 in (AA)
      and  nr = 1 in AA.

      it also has 0 values otherwise.

我的嘗試:我嘗試與:

from pyspark.sql.functions import when, col

condition = col("id1") == col("id2")
result = df.withColumn("val1", when(condition, 1)
result.show()

但是很快就發現該任務已經超出了我的pyspark技能水平。

編輯:

我正在嘗試運行:

condition1 = AA.id1 == AA.id2
condition2 = AA.nr == 1
condition3 = AA.cell1 == BB.cell  | AA.cell2 == BB.cell

result = BB.withColumn("val1", when(condition1 & condition2 & condition3, 1).otherwise(0)

在Zeppelin筆記本中給出錯誤:

Traceback (most recent call last):
  File "/tmp/zeppelin_pyspark-4362.py", line 344, in <module>
    code = compile('\n'.join(final_code), '<stdin>', 'exec', ast.PyCF_ONLY_AST, 1)
  File "<stdin>", line 6
    __zeppelin__._displayhook()
               ^
SyntaxError: invalid syntax

EDIT2:感謝您的更正,我錯過了一個右括號。 但是現在我明白了

ValueError: Cannot convert column into bool: please use '&' for 'and', '|' for 'or', '~' for 'not' when building DataFrame boolean expressions.

這很尷尬,因為我已經在使用這些運算符。

我認為最好的方法可能是將兩個數據框連接起來,然后可以在when子句中對條件進行建模。 我認為,如果使用withColumn創建一個新列,它將遍歷當前數據幀中的值,但是我認為您無法訪問另一個數據幀中的值,並且期望它也遍歷該行中的所有行。 以下代碼應滿足您的要求:

df_aa = spark.createDataFrame([
(1,1,0,"ab2", "ac3"),   
(1,1,1,"dg6", "jf2"),   
(2,1,1,"84d", "kf6"),   
(2,2,1,"89m", "k34"),   
(3,1,0,"5bd", "nc4")
], ("id1", "id2","nr","cell1","cell2"))

df_bb = spark.createDataFrame([
(1, 1, "x","ab2"),  
(1, 1, "a","dg6"),  
(2, 1, "b","84d"),  
(2, 2, "t","89m"),  
(3, 1, "d", "5bd")
], ("a", "b","use","cell"))

cond = (df_bb.cell == df_aa.cell1)|(df_bb.cell == df_aa.cell2)
df_bb.join(df_aa, cond, how="full").withColumn("val1", when((col("id1")==col("id2")) & ((col("cell")==col("cell1"))|(col("cell")==col("cell2"))) & (col("nr")==1), 1).otherwise(0)).withColumn("val2", when(~(col("id1")==col("id2")) & ((col("cell")==col("cell1"))|(col("cell")==col("cell2"))) & (col("nr")==1), 1).otherwise(0)).show()

結果看起來像:

+---+---+---+----+---+---+---+-----+-----+----+----+
|  a|  b|use|cell|id1|id2| nr|cell1|cell2|val1|val2|
+---+---+---+----+---+---+---+-----+-----+----+----+
|  1|  1|  x| ab2|  1|  1|  0|  ab2|  ac3|   0|   0|
|  1|  1|  a| dg6|  1|  1|  1|  dg6|  jf2|   1|   0|
|  2|  1|  b| 84d|  2|  1|  1|  84d|  kf6|   0|   1|
|  2|  2|  t| 89m|  2|  2|  1|  89m|  k34|   1|   0|
|  3|  1|  d| 5bd|  3|  1|  0|  5bd|  nc4|   0|   0|
+---+---+---+----+---+---+---+-----+-----+----+----+

可能我什至不需要檢查條件cell==cell1|cell==cell2因為這幾乎是cell==cell1|cell==cell2條件,但是為了使when條件類似於您的要求,我把它放在了那里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM