Подсказка типа, когда функции numpy возвращают серии pandas или фреймы данных

#python #pandas #numpy #type-hinting

#python #pandas #numpy #тип-намекающий #подсказка типа

Вопрос:

При использовании подсказок типа Python, как мне обрабатывать функции numpy, которые возвращают объекты pandas при применении к таким?

Например, когда я пишу

 import numpy as np
import pandas as pd
def clip_probability(probability: pd.Series) -> pd.Series:
    return np.clip(
        probability,
        0,
        1,
    )
  

Я получаю, Expected type 'Series', got 'ndarray' instead хотя np.clip возвращает серию, когда первый аргумент равен единице.

В случае, если существует решение для конкретной среды разработки, я использую PyCharm 2020.

Комментарии:

1. В данном конкретном случае np.clip его можно было бы заменить на pd.Series.clip , IIUC.

Ответ №1:

Вы пробовали использовать возврат функции? Обычно Numpy и Pandas хороши в приведении между их типами. Вот так:

 return pd.Series(np.clip(
        probability,
        0,
        1,
    )
)
  

Комментарии:

1. Я надеялся на решение без изменений кода (хотя это функциональный отказ, это все равно означает дополнительные вызовы функций). Обратите внимание, что вывод np.clip уже pd.Series

Ответ №2:

Я бы использовал typing.cast :

 from typing import cast

def clip_probability(probability: pd.Series) -> pd.Series:
    out = np.clip(
        probability,
        0,
        1,
    )
    return cast(pd.Series, out)
  

Это ничего не делает во время выполнения, но сигнализирует проверяющему типу, что out это действительно серия Pandas.

Комментарии:

1. Просто из любопытства, это буквально ничего не делает во время выполнения, с поддержкой на уровне интерпретатора, или это все еще переводится в несколько инструкций байтового кода?

2. (На данный момент я отклонил ответ, на всякий случай, если кто-нибудь придет и покажет чистый способ обезьяньих подсказок типа патча. Таким образом, мне не пришлось бы выполнять это приведение каждый раз, когда я вызываю np.clip / np.exp etc., но только один раз для каждого.)

3. Это один дополнительный вызов функции, который возвращается немедленно: github.com/python/typing/blob/master/src/typing.py#L1436-L1444 . Я не думаю, что вы можете сделать свою серию Pandas достаточно маленькой, чтобы это имело значение.

4. Я согласен с этим, мне было просто любопытно. В любом случае, дополнительный исходный код каждый раз, когда я вызываю такие функции, все еще немного беспокоит меня. Если ни у кого нет ничего более краткого, я повторно приму

Ответ №3:

np.clip возвращает ndarray (см. https://numpy.org/doc/stable/reference/generated/numpy.clip.html ).

Сначала вам нужно преобразовать этот ndarray в серию Pandas:

 return pd.Series(np.clip(
        probability,
        0,
        1,
    ))
  

Комментарии:

1. import numpy as np; import pandas as pd; type(np.clip(pd.Series([0,2]), 0, 1))