如果列值与另一个DF列表中的值匹配,则将值添加到DF

时间:2020-09-07 10:51:45

标签: python dataframe pyspark

我有一个DF1

+---------------+                                                               
|        colName|
+---------------+
|              a|
|              m|
|              f|
|              o|
+---------------+

还有另一个DF2

+---------------+                                                               
|            col|
+---------------+
|    [a,b,b,c,d]|
|      [e,f,g,h]|
|        [i,j,k]|
|    [l,m,n,o,p]|
+---------------+

如果存储在DF2.col中的列表具有DF1.colName中的元素,则新的DataFrame(或DF2)应为:

+---------------+---------------+                                                               
|            col|           bool|
+---------------+---------------+
|      [a,b,c,d]|              1|              #Since "a" was in `DF1.colName`
|      [e,f,g,h]|              1|              #Since "f" was in `DF1.colName`
|        [i,j,k]|              0|              #Since no element was not in `DF1.colName`
|    [l,m,n,o,p]|              1|              #Since "f" was in `DF1.colName`
+---------------+---------------+

我以前曾想过使用UserDefinedFunction和Pandas函数isIn(),但无济于事。任何可以帮助我指导的事情都将不胜感激。谢谢。

3 个答案:

答案 0 :(得分:2)

您可以将值转换为set并使用isdisjoint

s = set(DF1.colName)
DF2['bool'] = DF2['col'].apply(lambda x: not set(x).isdisjoint(s)).astype(int)

print (DF2)
               col  bool
0  [a, b, b, c, d]     1
1     [e, f, g, h]     1
2        [i, j, k]     0
3  [l, m, n, o, p]     1

或者使用交集,将False转换为bool,将其转换为空集,然后将True, False转换为1,0的整数:

s = set(DF1.colName)
DF2['bool'] = DF2['col'].apply(lambda x: bool(set(s).intersection(x))).astype(int)

print (DF2)
               col  bool
0  [a, b, b, c, d]     1
1     [e, f, g, h]     1
2        [i, j, k]     0
3  [l, m, n, o, p]     1

答案 1 :(得分:2)

尝试一下

df2['bool'] = df2.col.apply(lambda x: any(df1.colName.isin(x))).astype(int)
print(df2)

输出:

               col  bool
0  [a, b, b, c, d]     1
1     [e, f, g, h]     1
2        [i, j, k]     0
3  [l, m, n, o, p]     1

答案 2 :(得分:1)

使用pyspark,您可以使用array_intersect进行检查,然后使用when+otherwise使用case语句确定数组的大小;

arr = df1.select("colName").rdd.flatMap(lambda x:x).collect()
size = F.size(F.array_intersect("col",F.array([F.lit(i) for i in arr])))
df2.withColumn("t",F.when(size>0,1).otherwise(0)).show()

+---------------+---+
|            col|  t|
+---------------+---+
|[a, b, b, c, d]|  1|
|   [e, f, g, h]|  1|
|      [i, j, k]|  0|
|[l, m, n, o, p]|  1|
+---------------+---+