首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String的Cython类型列表

问String的Cython类型列表
EN

Stack Overflow用户
提问于 2017-07-05 13:52:41
回答 1查看 667关注 0票数 1

我试图使用cython来提高循环的性能,但是我遇到了一些问题,声明输入的类型。

如何在类型化的结构中包含一个字段,它是一个字符串,可以是“前台”,也可以是“后”

我有一个类似于以下内容的np.recarray (注意,recarray的长度作为编译时是未知的)

代码语言:javascript
复制
import numpy as np
weights = np.recarray(4, dtype=[('a', np.int64),  ('b', np.str_, 5), ('c', np.float64)])
weights[0] = (0, "front", 0.5)
weights[1] = (0, "back", 0.5)
weights[2] = (1, "front", 1.0)
weights[3] = (1, "back", 0.0)

以及字符串列表和pandas.Timestamp的输入。

代码语言:javascript
复制
import pandas as pd
ts = pd.Timestamp("2015-01-01")
contracts = ["CLX16", "CLZ16"]

我正在尝试计算下面的循环

代码语言:javascript
复制
def ploop(weights, contracts, timestamp):
    cwts = []
    for gen_num, position, weighting in weights:
        if weighting != 0:
            if position == "front":
                cntrct_idx = gen_num
            elif position == "back":
                cntrct_idx = gen_num + 1
            else:
                raise ValueError("transition.columns must contain "
                                 "'front' or 'back'")
            cwts.append((gen_num, contracts[cntrct_idx], weighting, timestamp))
    return cwts

我的尝试包括在cython中将weights输入作为结构输入,在文件struct_test.pyx中输入,如下所示

代码语言:javascript
复制
import numpy as np
cimport numpy as np


cdef packed struct tstruct:
    np.int64_t gen_num
    char[5] position
    np.float64_t weighting


def cloop(tstruct[:] weights_array, contracts, timestamp):
    cdef tstruct weights
    cdef int i
    cdef int cntrct_idx

    cwts = []
    for k in xrange(len(weights_array)):
        w = weights_array[k]
        if w.weighting != 0:
            if w.position == "front":
                cntrct_idx = w.gen_num
            elif w.position == "back":
                cntrct_idx = w.gen_num + 1
            else:
                raise ValueError("transition.columns must contain "
                                 "'front' or 'back'")
            cwts.append((w.gen_num, contracts[cntrct_idx], w.weighting,
                         timestamp))
    return cwts

但我正在接收运行时错误,我认为这些错误与char[5] position有关。

代码语言:javascript
复制
import pyximport
pyximport.install()
import struct_test

struct_test.cloop(weights, contracts, ts)

ValueError: Does not understand character buffer dtype format string ('w')

此外,我还有点不清楚如何键入contracts和timestamp。

EN

回答 1

Stack Overflow用户

发布于 2017-07-05 21:34:44

您的ploop (没有timestamp变量)生成:

代码语言:javascript
复制
In [226]: ploop(weights, contracts)
Out[226]: [(0, 'CLX16', 0.5), (0, 'CLZ16', 0.5), (1, 'CLZ16', 1.0)]

没有循环的等价函数:

代码语言:javascript
复制
def ploopless(weights, contracts):
    arr_contracts = np.array(contracts) # to allow array indexing
    wgts1 = weights[weights['c']!=0]
    mask = wgts1['b']=='front'
    wgts1['b'][mask] = arr_contracts[wgts1['a'][mask]]
    mask = wgts1['b']=='back'
    wgts1['b'][mask] = arr_contracts[wgts1['a'][mask]+1]
    return wgts1.tolist()

In [250]: ploopless(weights, contracts)
Out[250]: [(0, 'CLX16', 0.5), (0, 'CLZ16', 0.5), (1, 'CLZ16', 1.0)]

我利用了一个事实,即返回的元组列表具有与输入weight数组相同的布局(int、str、int)。因此,我只是制作一个weights的副本,并替换b字段的选定值。

注意,我在mask索引之前使用了字段选择索引。布尔mask生成一个副本,因此我们必须小心索引顺序。

我猜没有循环的数组版本将在时间上与cloop (在现实的数组上)竞争。cloop中的字符串和列表操作可能限制了它的加速。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44928217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档