pyspark在数据帧中查找超出范围的值

2024-09-28 19:11:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我在pyspark中有两个数据帧。我试图将一个数据帧与另一个数据帧进行比较,以查看值是否在范围内

下面是dataframe的一个示例

数据帧df:

enter image description here

数据帧dfcompare:

enter image description here

我正在寻找的输出:

enter image description here

我目前拥有的代码如下:


def cal_OTRC(spark_df):
  compare = df.compare.fillna(0)
  df = spark_df.agg(*(F.count(F.when((F.col(c) > compare.astype(int).values.tolist()[0]) | (F.col(c) < compare[c].astype(int).values.tolist()[1]), c)).alias(c)  for c in spark_df.columns ))
  return df

out_of_range_count = cal_OTRC(df).to_koalas().rename(index={0: 'outofRange'})

然而,这段代码适用于小表,但对于大表,这是非常缓慢的。对于大型表,可以做哪些改进来加快运行速度


Tags: 数据代码dataframedfcountcolsparkpyspark
1条回答
网友
1楼 · 发布于 2024-09-28 19:11:32

您可以将dfcompare翻译成一个dict,每个列有一个minmax条目

compare = {'empid': {'min': 1, 'max': 3}, 'salary': {'min': 100, 'max': 400}}

然后,如果值超出范围,列表达式可以计算每列

df = <load data>
df = df.select("*", *[ F.when((F.col(c)< compare[c]['min']) | (F.col(c)>compare[c]['max']), 1) \
    .otherwise(0).alias("out_{}".format(c)) for c in compare])

这将为每行和每列生成一个01

+  -+   +    -+     +
|empid|salary|out_empid|out_salary|
+  -+   +    -+     +
|    1|    50|        0|         1|
|    2|   600|        0|         1|
|    3|   300|        0|         0|
|    4|   400|        1|         0|
|    5|  1000|        1|         1|
+  -+   +    -+     +

最后对out列求和得到

df = df.select( *[F.sum("out_{}".format(c)) for c in compare])
+       +       -+
|sum(out_empid)|sum(out_salary)|
+       +       -+
|             2|              3|
+       +       -+

相关问题 更多 >