Неверный результат при применении функции к сериям панд - PullRequest
0 голосов
/ 19 октября 2018

Когда я пытался применить две версии функции, чистый python против cython, к серии pandas, были получены два разных результата

import numpy as np
import pandas as pd
from libc.math cimport lround

def py_func(n):
    return round(13 * n / 37)

cdef int cy_func(int n):
    return lround(13 * n / 37)

arr = np.arange(1000, 12000, 2000)

series = pd.Series(arr)
print("Original series:")
print(series)

series1 = series.apply(py_func)
series2 = series.apply(cy_func)

print("\nApplied with python function:")
print(series1)

print("\nApplied with cython function:")
print(series2)

Результаты:

Original series:
0     1000
1     3000
2     5000
3     7000
4     9000
5    11000
dtype: int32

Applied with python function:
0     351
1    1054
2    1757
3     688
4    1391
5     322
dtype: int64

Applied with cython function:
0     351
1    1054
2    1757
3    2459
4    3162
5    3865
dtype: int64

Мы видим, что при применении функции python мы получаем неверные результаты в последних трех числах.Хотя функция cython дает правильные результаты.

Почему функция python дает неправильные результаты?И как это исправить?

Обновление

Вышеуказанные результаты были получены на Windows 10 64-bit.Однако, когда я попробовал 64-битную версию Ubuntu 18.04 на одном компьютере (используя WSL), обе серии дали правильные результаты.В обоих случаях у меня есть Cython==0.29, numpy==1.15.2, pandas==0.23.4, также протестированный с Cython==0.28.5, numpy==1.14.5, pandas==0.23.3.

Есть еще одно отличие в результатах: с Windows 10 dtype оригинальной серии составляет int32, тогда как dtype в Ubuntu 18.04 - это int64.dtype обеих последовательностей результатов int64 в обеих ОС.

1 Ответ

0 голосов
/ 23 октября 2018

При использовании MinGW, MS_WIN64 не определено, что используется для определения SIZEOF_VOID_P следующим образом в pyconfig.h.

#if defined(MS_WIN64)
...
#   define SIZEOF_VOID_P 8
...
#elif defined(MS_WIN32)
...
#   define SIZEOF_VOID_P 4
...
#endif

SIZEOF_VOID_P затем используется в pyport.h

#ifndef PYLONG_BITS_IN_DIGIT
#if SIZEOF_VOID_P >= 8
#define PYLONG_BITS_IN_DIGIT 30
#else
#define PYLONG_BITS_IN_DIGIT 15
#endif
#endif

Решение заключается в передаче -DMS_WIN64 при компиляции с MinGW.

Связанные Python ticket и обсуждение в группе пользователей Cython .

...