pandas 使用col值透视表,并使用col名称作为筛选器以在spark中返回新值

krcsximq  于 2022-11-20  发布在  Spark
关注(0)|答案(1)|浏览(125)

假设我有两个表。在下面的例子中,只有两个列发生变化,但不确定如果透视将工作良好的10列。表1:

--------------------------
|id  |filtercol| inputid1|
--------------------------
|100| 10       | 4       |
|108| 10       | 5       | 
|200| 9        | 4       |
|106| 9        | 6       |
|110| 11       | 7       |
|130| 9        | 7       |    
--------------------------

表二:

---------------------------------
    |a      |  b       | c       | d |
    ---------------------------------
    |"hello"| 1        | 4       | 6 |
    |"world"| 2        | 5       | 6 |
    |"test" | 3        | 4       | 7 |
    ---------------------------------

我希望决赛桌

----------------------------------
    |a      |  b       | 10      | 11|
    ----------------------------------
    |"hello"| 1        | 100     |   |
    |"world"| 2        | 108     |   |
    |"test" | 3        | 100     |110|
    ---------------------------------

因此,c col将更改为10,d col将重命名为11。
然后在filtercol列名中使用10作为表1的过滤器,并使用列c和d中的值作为列inputid1的查找值。无论找到什么值,我们都将表2的值更改为表1中的id值。
例如,对于第一行,新表的第10列中有100,因为我们使用了该行中的原始值4作为列inputid1的查找,然后使用新的c列名10作为列filtercol上的过滤器,并获得了ID 100,因此现在在此列中将4替换为100。
第11列返回空值的原因是,当使用6作为筛选列时,在使用6作为筛选列后,查找中没有返回值。
我正在考虑可能的加入和过滤,但似乎不是很好的解决方案,因为让我们说,我有col e,f,g,hi,j检查太多。

df2 = df.withColumnRenamed("c","10")
   df2 = df.withColumnRenamed("d","11")



table3df = (
    df1.join(df2,
                        df1.inputid1 == df2.10, how='left')
)

table3df = table3df.filter(col("filtercol") ==int(col("10"))
voj3qocg

voj3qocg1#

我对你的例子做了一些尝试,还没有完全实现。你没有提到当c列中有多个值匹配时该怎么办。我用max解决了这个问题,它给了我一个与你所期望的不同的答案。

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, when

spark = SparkSession.builder.getOrCreate()

table1_df = spark.sql("""
SELECT 100 as id, 10 as filtercol, 4 as inputid1 
UNION ALL
SELECT 108, 10, 5 
UNION ALL
SELECT 200, 9, 4 
UNION ALL
SELECT 106, 9, 6 
UNION ALL
SELECT 110, 11, 7 
UNION ALL
SELECT 130, 9, 7
""").alias("table1")

table2_df = spark.sql("""
SELECT 'hello' as a, 1 as b, 4 as c, 6 as d 
UNION ALL
SELECT 'world', 2, 5, 6 
UNION ALL
SELECT 'test', 3, 4, 7
""").alias("table2")

j = table2_df.join(table1_df.alias("join_c"), col("table2.c") == col("join_c.inputid1")).join(table1_df.alias("join_d"), col("table2.d") == col("join_d.inputid1"))

j.show()

j.select(
    "table2.a",
    "table2.b",
    when(col("join_c.filtercol") == "10", col("join_c.id")).alias("10"),
    when(col("join_d.filtercol") == "11", col("join_c.id")).alias("11")
).groupby("a", "b").max().show()

+-----+---+------+-------+-------+
|    a|  b|max(b)|max(10)|max(11)|
+-----+---+------+-------+-------+
|hello|  1|     1|    100|   null|
|world|  2|     2|    108|   null|
| test|  3|     3|    100|    200|
+-----+---+------+-------+-------+

相关问题