Какова внутренняя реализация pandas Series.map ()? - PullRequest
3 голосов
/ 02 февраля 2020

Я замечаю, что pandas Series.map () очень быстро для отображения в диктовке

Подготовьте данные, как показано ниже:

a=np.random.randint(0,1000,10**5)
s=pd.Series(a)
d=dict(zip(np.arange(1000),np.random.random(1000)))

хронирование

%timeit -n10 s.map(d)
%timeit -n10 np.vectorize(d.get)(a)

дает

1.42 ms ± 168 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
20.6 ms ± 386 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

, где вторым подходом является типичная рекомендация для выполнения numpy отображения dict, которое я нашел в stackoverflow.

Существует еще одно типичное решение numpy, как показано ниже

%%timeit -n10 
b = np.copy(a)
for k, v in d.items():
    b[a==k] = v

, которое дает

43.9 ms ± 2.8 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

это еще медленнее, а что хуже, оно дает неверное результат. Поскольку b является типом int, присваивание b[a==k] = v вернет b, все нули будут!

Поэтому мне интересно, какова внутренняя реализация pandas Series.map ()? Это реализовано в numpy? Что такое numpy, эквивалентный Series.map (), который имеет такую ​​же производительность? Я попытался покопаться в исходном коде Series.map (), но не могу этого понять.

1 Ответ

4 голосов
/ 02 февраля 2020

Series.map вызовет _map_values(), который является частью pandas / core / base.py

Вы используете диктовку, чтобы вы go до первого if is_dict_like(mapper): предложение, чтобы получить mapper, а затем в строках 1161-1162 вы получите функцию отображения для этого базового c случая (без расширения типа по умолчанию na_action=None)

else:
    map_f = lib.map_infer

Если вы затем go к этой части кода, найденной в pandas / _libs / lib.pyx, вы увидите, что map_infer реализован в cython.


Как они отмечают в комментариях, это только так быстро для определенных c входов:

# we can fastpath dict/Series to an efficient map
# as we know that we are not going to have to yield
# python types
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...