Как разместить столбец и сохранить нулевые значения в отдельной группе - PullRequest
0 голосов
/ 05 марта 2020

У меня есть столбец с непрерывной переменной, и я хотел добавить его для построения графика. Тем не менее, этот столбец также содержит нулевые значения.

Я использовал следующий код, чтобы скопировать его:

def a(b):
  if b<= 20: return "<= 20"
  elif b<= 40: return "20 < <= 40"
  elif b<= 45: return "40 < <= 45"
  else: return "> 45"
audf = udf(a, StringType())
data= data.withColumn("a_bucket", audf("b"))

Я работаю на Python 3 и выдает мне следующую ошибку:

TypeError: '<=' not supported between instances of 'NoneType' and 'int'

Я смотрю некоторые документы, в которых говорится, что Python 3 не позволяет сравнивать числа с нулевым значением. Но есть ли способ для меня, чтобы выбросить эти нулевые значения в отдельную группу, чтобы я не выбрасывал данные. Это не плохие данные.

Спасибо.

1 Ответ

1 голос
/ 05 марта 2020

Вы можете сделать это без udf. Вот один из способов переписать ваш код и получить специальную корзину для значений null:

from pyspark.sql.functions import col, when

def a(b):
    return when(b.isNull(), "Other")\
        .when(b <= 20, "<= 20")\
        .when(b <= 40, "20 < <= 40")\
        .when(b <= 45, "40 < <= 45")\
        .otherwise("> 45")

data = data.withColumn("a_bucket", a(col("b")))

Однако более общее решение позволит вам передать список блоков и динамически вернуть вывод корзины (не проверено):

from functools import reduce

def aNew(b, buckets):
    """assumes buckets are sorted"""
    if not buckets:
        raise ValueError("buckets can not be empty")
    return reduce(
        lambda w, i: w.when(
            b.between(buckets[i-1], buckets[i]), 
            "{low} < <= {high}".format(low=buckets[i-1], high=buckets[i]))
        ),
        range(1, len(buckets)),
        when(
            b.isNull(), 
            "Other"
        ).when(
            b <= buckets[0], 
            "<= {first}".format(first=buckets[0])
        )
    ).otherwise("> {last}".format(last=buckets[-1]))

data = data.withColumn("a_bucket", aNew(col("b"), buckets=[20, 40, 45]))
...