我在data frame
中有一个pyspark
,如下所示。
+-----+---+---+----+
|tests|val|asd|cnty|
+-----+---+---+----+
|test1| Y| 1|null|
|test2| N| 2| UK|
| null| Y| 1| UK|
|test1| N| 2|null|
|test1| N| 3|null|
|test3| N| 4| AUS|
|test4| Y| 5|null|
+-----+---+---+----+
我希望在任何给定的tests
或cnty
具有val Y
时更新该值,然后更新该tests
或{{1}的所有值应该更新为cnty
。如果不是那么他们有什么价值。
我在下面做了
Y
以上并没有给我想要的结果。您可以看到from pyspark.sql import Window
import pyspark.sql.functions as f
df1 = df.select('tests', f.max('val').over(Window.partitionBy('tests')).alias('val'), 'asd', 'cnty')
+-----+---+---+----+
|tests|val|asd|cnty|
+-----+---+---+----+
|test1| Y| 1|null|
|test1| Y| 2|null|
|test1| Y| 3|null|
|test2| N| 2| UK|
|test3| N| 4| AUS|
|test4| Y| 5|null|
| null| Y| 1| UK|
+-----+---+---+----+
我test2
cnty
UK
val
N
cnty
UK
val
Y
val
Y
该记录的result
为WebBrowser
然后根据我的要求,这两个记录的JavaScript
应为HKEY_CURRENT_USER
SOFTWARE
Microsoft
Internet Explorer
Main
FeatureControl
FEATURE_BROWSER_EMULATION
myapp.exe = (DWORD) 00011000
。但async
中并非如此。
答案 0 :(得分:2)
您只检查了测试列,但是您忘记检查cnty列。为此你需要另一个windowSpec for cnty列,并使用when
内置函数组合两个windowSpecs来获得你想要的结果
from pyspark.sql import window as w
windowSpec1 = w.Window.partitionBy('tests').orderBy('asd')
windowSpec2 = w.Window.partitionBy('cnty').orderBy('asd')
from pyspark.sql import functions as f
df = df.select(f.col('tests'), f.when(f.max('val').over(windowSpec1)== 'Y', 'Y').otherwise(f.when(f.max('val').over(windowSpec2)== 'Y', 'Y').otherwise(f.col('val'))).alias('val'), f.col('asd'), f.col('cnty'))
df.show(truncate=False)
应该给你
+-----+---+---+----+
|tests|val|asd|cnty|
+-----+---+---+----+
|test4|Y |5 |null|
|test3|N |4 |AUS |
|test1|Y |1 |null|
|test1|Y |2 |null|
|test1|Y |3 |null|
|test2|Y |2 |UK |
|null |Y |1 |UK |
+-----+---+---+----+
我希望这能解释为什么你没有得到理想的结果。
<强>更新强>
以上解决方案要求两个window
函数同时运行,这可能会导致一些内存问题。您可以分别运行一个window
函数来分别检查tests
和cnty
列
from pyspark.sql import window as w
windowSpec1 = w.Window.partitionBy('tests').orderBy('asd')
windowSpec2 = w.Window.partitionBy('cnty').orderBy('asd')
from pyspark.sql import functions as f
df = df.withColumn('val', f.when(f.max('val').over(windowSpec1)== 'Y', 'Y').otherwise(f.col('val')))\
.withColumn('val', f.when(f.max('val').over(windowSpec2)== 'Y', 'Y').otherwise(f.col('val')))
这将产生相同的结果。
答案 1 :(得分:1)
您可以尝试以下方法。将数据帧左连接到使用&#39; Y
&#39;过滤的同一数据帧右边的值:如果找到则应用Y
,否则获取现有值。
df.alias('a').join(
df.filter(col('val')='Y').alias('b'),
on=(col('a.tests') == col('b.tests')) | (col('a.cnty') == col('b.cnty')),
how='left'
)
.withColumn('final_val',when(col('b.val').isNull(), col('a.val')).otherwise(col('b.val')))
.select('a.tests','a.asd','a.cnty','final_val')
唯一的问题是,可能存在重复问题,但最好是对数据进行测试,并在必要时进行重复数据删除。