Cython with dict same as python



我已经尝试了一些可用的解决方案,但无法通过以下Cython代码获得任何加速。

cython代码所花费的时间与其python等效代码相同。

calculate_sum.pyx

# key_id: it is a string
# values_dict: it is a dictionary with key as str and values as numpy.ndarray consisting of floats
# e.g.: print(values_dict['abc']) will give out numpy.ndarray([0.01, 1.01, 2.05]). values_dict has many such entries.
cpdef dict calculate_sum(str key_id, dict values_dict):
cdef dict result_dict = {}
cdef str check_id
for check_id, values in values_dict.items():
if check_id != key_id:
result_dict[check_id] = sum(values)
return result_dict

setup.py

from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize('calculate_sum.pyx'))

main.py

import calculate_sum
# ...
# piece of code which computes values_dict
# ...
key_id = 'abc'
sum_value = calculate_sum.calculate_sum(key_id, values_dict)

任何建议/帮助将不胜感激。

总的来说,我认为 Cython 不会帮助这段代码:它主要是操作 Python 对象,并且从中加速往往很小。一些建议:

  • 对于 numpy 数组,x.sum()sum(x)快得多(对于我 PC 上的快速测试用例,速度大约快 60 倍(。如果您知道这些值将是 Numpy 数组,请直接执行此操作。
  • 可以重写代码以使用字典理解。这可能会获得一点速度(主要是因为它可能能够预先分配正确的大小(。
  • 可能值得省略循环中的if语句,并计算每个键的总和(然后删除key_id(。计时。

组合的:

def calculate_sum(key_id, values_dict):
result_dict = { key: values.sum() for key, values in values_dict.items() }
del result_dict[key_id]
return result_dict

请注意,我已经放弃了所有 Cython 的东西,因为我认为它在这里毫无意义。我对基准测试没有太大的兴趣,但我怀疑对sum的更改将产生主要差异。


您可能想要查看的另一种方法是使用 Pandas(此处的代码未经测试......假设你已使用values = pd.DataFrame.from_dict(values_dict)创建了values数据帧,则:

def calculate_sum(key_id, values):
return values.sum(axis=1).drop(key_id)

在所有长度相同的 Numpy 数组中,这将效果最好(尽管我认为这不是绝对要求(。你的目标是普遍使用熊猫,而不是经常在dict之间转换。同样,Cython在这里无济于事。

最新更新