将数据框列类型更改为 int32

Changing a dataframe column type to int32

我正在尝试将数据帧列从 Python 传递到 Cython:

Python代码

evaluate_c(
        AnimalLogicPy(data[COL_ANIMAL_ID].values,              
        data[COL_ANIMAL_POWER].values,
        )

Cython 代码

cpdef void evaluate_c(
        int[:] animal_ids,
        int[:] animal_power,
        ):

Python 一侧 data[COL_ANIMAL_ID]data[COL_ANIMAL_POWER] 的类型为:int64

但是我收到以下错误:

ValueError: Buffer dtype mismatch, expected 'int' but got 'long'

我想在 Cython 中使用 int 值。我读过一些书,我认为这是因为有问题的数据框列属于 int64 类型,我认为它变得很长,应该是 int32.

我已经尝试在 Python 端使用以下方法更改类型:

data.astype({COL_ANIMAL_ID: 'int32'}).dtypes
data.astype({COL_ANIMAL_POWER: 'int32'}).dtypes

但我仍然得到 ValueError。

如何将 Python 端的列类型从 int64 更改为 int32?

您可以将其转换为具有正确 dtype 的 NumPy 数组。

有多种方法可以实现这一点,其中最直接的是通过 .to_numpy() 方法:

data[COL_ANIMAL_ID].to_numpy('int32')

为了给你一个最小的工作示例,让我们假设我们有以下 Cython 函数(为简单起见,使用 IPython 的 Cython 魔法编译):

%%cython -c-O3 -c-march=native -a
#cython: language_level=3, boundscheck=False, wraparound=False, initializedcheck=False, cdivision=True, infer_types=True


cpdef int summer(int [:] data, int n):
    cdef int result = 0
    for i in range(n):
        result += data[i]
    return result

然后下面的代码有效:

import pandas as pd
import numpy as np


np.random.seed(0)
df = pd.DataFrame(np.random.randint(0, 100, (3, 4)))
print(df)
#     0   1   2   3
# 0  44  47  64  67
# 1  67   9  83  21
# 2  36  87  70  88


arr = np.array(df[0], dtype=np.int32)
print(summer(arr, arr.size))  # the array is fed to the Cython func
# 147

print(summer(df[0].values.astype(np.int32), df[0].size))  # directly from the Pandas's series
# 147

print(summer(df[0].to_numpy(dtype=np.int32), df[0].size))  # even more concisely
# 147

print(df[0].sum())  # checking that the result is correct
# 147