当我尝试将两个版本的函数(纯python vs cython)应用于pandas系列时,会获得两个不同的结果
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.changer_ico)
.setContentTitle(context.getString(R.string.service_ready))
.setContentIntent(pendingIntent)
.addAction(R.drawable.ic_key_black_24dp, context.getString(R.string.turn_on), pendingIntent)
.setAutoCancel(true);
Notification notification = notificationBuilder.build();
NotificationChannel channel = new NotificationChannel("1903",
context.getString(R.string.user_notify), NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
notificationManager.notify(1903, notification);
结果是
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)
我们可以看到,在应用python函数时,我们在最后三个数字中获得了错误的结果。 cython函数产生正确的结果。
为什么python函数会产生不正确的结果?以及如何解决?
更新
以上结果是在Windows 10 64位系统上获得的。但是,当我在同一台计算机(使用WSL)上尝试使用Ubuntu 18.04 64位时,两个系列都具有正确的结果。在这两种情况下,我都有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
,并且也经过了Cython==0.29, numpy==1.15.2, pandas==0.23.4
的测试。
结果还有另一个差异:在Windows 10中,原始系列的Cython==0.28.5, numpy==1.14.5, pandas==0.23.3
是dtype
,而在Ubuntu 18.04上的int32
是dtype
。在两个操作系统中,两个结果系列的int64
均为dtype
。
答案 0 :(得分:1)
使用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
解决方案是在使用MinGW进行编译时传递-DMS_WIN64
。