在python

时间:2015-10-09 18:16:25

标签: python performance python-2.7 binary binaryfiles

我们用this FPGA counter.计算光子和时间标记我们每分钟获得大约500MB的数据。我在十六进制字符串中获得32位数据 * 使用little-endian字节顺序存储的32位有符号整数。目前我这样做:

def getall(file):
    data1 = np.memmap(file, dtype='<i4', mode='r')

    d0=0
    raw_counts=[]
    for i in data1:

        binary = bin(i)[2:].zfill(8)
        decimal = int(binary[5:],2)

        if binary[:1] == '1':
            raw_counts.append(decimal)

    counter=collections.Counter(raw_counts)
    sorted_counts=sorted(counter.items(), key=lambda pair: pair[0], reverse=False)
    return counter,counter.keys(),counter.values()

我认为这部分(binary = bin(i)[2:].zfill(8);decimal = int(binary[5:],2))正在减慢这个过程。(不,不是。我通过剖析我的程序发现了。)有没有办法加速它?到目前为止,我只需要[5:]中的二进制位。我不需要所有32位。所以我认为将32位解析为持续27位需要大部分时间。谢谢,

*更新1

J.F.Sebastian指出我不是十六进制字符串。

*更新2

如果有人需要,这是最终代码。我最终使用np.unique而不是集合计数器。最后,我转换回收集柜台,因为我想累积计数。

#http://stackoverflow.com/questions/10741346/numpy-most-efficient-frequency-counts-for-unique-values-in-an-array
def myc(x):
    unique, counts = np.unique(x, return_counts=True)
    return np.asarray((unique, counts)).T


def getallfast(file):
    data1 = np.memmap(file, dtype='<i4', mode='r')
    data2=data1[np.nonzero((~data1 & (31 <<1)))] & 0x7ffffff #See J.F.Sebastian's comment.
    counter=myc(data2)
    raw_counts=dict(zip(counter[:,0],counter[:,1]))
    counter=collections.Counter(raw_counts)

    return counter,counter.keys(),counter.values()

然而,对我来说,这个版本看起来是最快的版本。与先计数相比,data1[np.nonzero((~data1 & (31 <<1)))] & 0x7ffffff正在放慢速度并稍后转换数据binary = bin(counter[i,0])[2:].zfill(8)

def myc(x):
    unique, counts = np.unique(x, return_counts=True)
    return np.asarray((unique, counts)).T

def getallfast(file):
    data1 = np.memmap(file, dtype='<i4', mode='r')
    counter=myc(data1)
    xnew=[]
    ynew=[]
    raw_counts=dict()
    for i in range(len(counter)):
        binary = bin(counter[i,0])[2:].zfill(8)
        decimal = int(binary[5:],2)
        xnew.append(decimal)
        ynew.append(counter[i,1])
        raw_counts[decimal]=counter[i,1]


    counter=collections.Counter(raw_counts)
    return counter,xnew,ynew

1 个答案:

答案 0 :(得分:0)

我猜你可以尝试其中一个

可以使用二进制和fivebits=my_int&0x1f

如果你想要另一端的五位只是fivebits = my_int >> (32-5)

但实际上根据我的经验将它转换为字符串非常快......我认为这是多年前的一个瓶颈......在分析它之后我发现它不是