【问题标题】:Pyspark - add columns to dataframe based on values from different dataframePyspark - 根据来自不同数据框的值向数据框添加列
【发布时间】:2019-03-21 21:08:03
【问题描述】:

我有两个数据框。

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 是一个区间)。

我想在BBval1val2 中添加两列。条件如下。

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.

这很尴尬,因为我已经在使用这些运算符了。

【问题讨论】:

  • 你错过了otherwise(0)后面最后一行的右括号
  • 谢谢@gaw,我更正了它,但它并没有解决问题。
  • 您会收到错误消息,因为| 运算符的绑定比== 更强。所以你的条件3变成等于(列或列)等于列的列。然后它不知道如何将两列“或”

标签: python apache-spark pyspark apache-spark-sql


【解决方案1】:

在我看来,最好的方法可能是连接两个数据框,然后您可以在 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,因为这几乎是连接条件,但是为了使 when 条件类似于你的要求,我把它放在那里

【讨论】:

  • 如果您想确保条件应用相同的行(按索引),则可以为两个数据框创建一个额外的 id 列并用于连接
  • 似乎有效,但是,我正在尝试修改条件 cond = (df_bb.cell == df_aa.cell1)|(df_bb.cell == df_aa.cell2)&(df_aa.cell1 ! = 0)&(df_aa.cell2 != 0) 不添加 cell1 或 cell2 可能为 0 的行。但这似乎没有效果。
  • 您必须以不同的方式执行此操作:cond =((df_bb.cell == df_aa.cell1)|(df_bb.cell == df_aa.cell2)) &amp; (~(df_aa.cell1 == '0'))&amp; (~(df_aa.cell2 == '0')) 因为您通常会用 ~ 否定条件。将连接类型更改为“内部”以仅获取成功连接的记录也可能会有所帮助:使用 join(df_aa, cond, how="inner") 进行连接
猜你喜欢
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 2022-08-13
  • 1970-01-01
  • 2021-11-24
相关资源
最近更新 更多