Как использовать функцию fillna со столбцом с периодом в pyspark

Я попытался запустить fillna, чтобы вставить nan в столбец со специальным символом.

df = spark.createDataFrame(
    [(None, None), ('U1', None), ('U3', 1.0)], 
    ['USER_ID', 'a.b']
)

Я попытался

df = df.fillna({"`a.b`": float("nan")})

также

df = df.fillna({"a.b": float("nan")})

Оба они не работают, у кого есть опыт в этом?


person yi wang    schedule 14.08.2020    source источник
comment
Какая версия искры?   -  person pault    schedule 14.08.2020


Ответы (2)


Похоже, что существует ограничение pyspark.sql.DataFrame.fillna(), который не позволяет вам указывать имена столбцов с точками в них, когда вы используете параметр value в качестве словаря.

Из документов:

value — int, long, float, string, bool или dict. Значение для замены нулевых значений. Если значением является словарь, то подмножество игнорируется, а значение должно быть сопоставлением имени столбца (строки) со значением замены. Значение замены должно быть целым, длинным, числом с плавающей запятой, логическим значением или строкой.

Вы должны иметь возможность использовать fillna, используя другой синтаксис, который указывает параметры value и subset.

df.fillna(value=float("nan"), subset=["a.b"]).show()
#+-------+---+
#|USER_ID|a.b|
#+-------+---+
#|   null|NaN|
#|     U1|NaN|
#|     U3|1.0|
#+-------+---+

Вышеупомянутое сработало для меня в Spark 2.4, но я не понимаю, почему это не должно работать в более старой версии.

Если у вас все еще есть проблемы, другой способ сделать это - временно переименуйте свои столбцы, вызовите fillna, а затем переименуйте столбцы обратно в исходные значения:

Здесь я переименую столбцы, чтобы заменить "." строкой "_DOT_", которую я намеренно выбрал, чтобы избежать конфликта с существующими подстроками в другие имена столбцов.

df.toDF(*[c.replace(".", "_DOT_") for c in df.columns])\
    .fillna({"a_DOT_b": float("nan")})\
    .toDF(*df.columns)\
    .show()
#+-------+---+
#|USER_ID|a.b|
#+-------+---+
#|   null|NaN|
#|     U1|NaN|
#|     U3|1.0|
#+-------+---+
person pault    schedule 14.08.2020

Это работает.

df = spark.createDataFrame([(None, None), ('U1', None), ('U3', 1.0)], ['USER_ID', 'a.b'])
df = df.fillna(float("nan"), ['`a.b`'])
df.show(10, False)

+-------+---+
|USER_ID|a.b|
+-------+---+
|null   |NaN|
|U1     |NaN|
|U3     |1.0|
+-------+---+
person Lamanus    schedule 14.08.2020
comment
работает в моем ноутбуке, это все еще не удалось - person yi wang; 14.08.2020
comment
Произошла ошибка: u'Не удается разрешить имя столбца a.b среди (USER_ID, a.b);' Трассировка (последний последний вызов): файл /usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/dataframe.py, строка 1672, in fillna return DataFrame(self._jdf.na().fill( значение, self._jseq(подмножество)), self.sql_ctx) Файл /usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/java_gateway.py, строка 1257, в - person yi wang; 14.08.2020
comment
какая версия искры и питона? - person Lamanus; 14.08.2020
comment
На самом деле, это работает, как только я проверил это снова. Спасибо - person yi wang; 21.12.2020