Как устранить ошибку mypy «значение типа row | none is not indexable» для фрейма данных pyspark?

Mypy выдает ошибку «Значение типа «Строка | Нет» не индексируется» для строки, начинающейся с «x=":

from pyspark.sql import DataFrame
from pyspark.sql import functions as f

def somefunction(df: DataFrame, column_name: str) -> DataFrame:
    x = df.select(f.min(f.col(column_name))).first()[0] 
    return df.withColumn('newcolumn', f.col(column_name) + x)

Как я могу добавить проверку типа, которая проходит через mypy?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
203
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

df.select(...) возвращает значение типа Row | None, что означает, что фактическое возвращаемое значение может быть Row или None. Вы не можете индексировать None, поэтому вы не можете индексировать значение типа Row | None, пока не убедитесь, что это определенно не так None. (По сути, интерфейс типа объединения — это пересечение отдельных типов: с A | B можно делать только то, что можно делать с A и B.)

Один из способов сделать это — использовать сужение типа: проверив, равно ли возвращаемое значение None, вы можете перейти к коду со статическим типом NoneType или к коду со статическим типом Row.

# reveal_type(result) == Row | None
result = df.select(f.min(f.col(column_name))).first()

if result is None:
    # reveal_type(result) == None
    do what needs to be done if no row is returned
else:
    # reveal_type(result) == Row
    x = result[0]
    return df.withColumn('new column', f.col(column_name) + x)

Возможно, вы знаете, что конкретный аргумент df.select не может потерпеть неудачу, но mypy — нет.


Другой вариант, если вы абсолютно уверены, что получите ответный знак Row, — использовать cast, чтобы раскрыть mypy секрет.

x = typing.cast(Row, df.select(...))[0]
return df.withColumn(...)

Однако это рискованно. mypy поверит cast, и если df.select(...) вернет None, вы получите ошибку времени выполнения, хотя mypy говорит, что все в порядке.

Другие вопросы по теме