【问题标题】:Fastest way to parse (split) binary bits in python在python中解析(拆分)二进制位的最快方法
【发布时间】:2015-10-09 18:16:24
【问题描述】:

我们用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 &amp; (31 &lt;&lt;1)))] &amp; 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

【问题讨论】:

  • 你分析过它吗?
  • 实际上我发现将其转换为字符串非常高效......比其他方法更有效......(至少在拍摄多个切片时)
  • 您的代码暗示输入不是“十六进制字符串”。您的输入包含使用 little-endian 字节顺序存储的 32 位有符号整数。要获得 27 个最低有效位,您可以使用按位运算:i &amp; 0x7ffffff(要有效地做到这一点,请使用矢量化 numpy 操作)。如果你做的一切都是正确的,那么你的任务应该是 I/O 绑定的(受存储输入文件的硬盘速度的限制)。 Counter() is slow on Python 2.
  • @J.F.Sebastian 你是对的。我的输入是使用 little-endian 字节顺序存储的 32 位有符号整数。我将研究向量化的 numpy。谢谢

标签: python performance python-2.7 binary binaryfiles


【解决方案1】:

我想你可以试试这 2 个中的一个

可以只取二进制位和fivebits=my_int&amp;0x1f

如果您想要另一端的五个位,只需 fivebits = my_int &gt;&gt; (32-5)

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

【讨论】:

  • 看起来 OP 想要(32-5) 位,即my_int &amp; 0x7ffffff
猜你喜欢
  • 2015-03-27
  • 2013-09-01
  • 2018-05-20
  • 2019-06-09
  • 1970-01-01
  • 2021-04-12
  • 2010-12-13
  • 2020-08-27
  • 1970-01-01
相关资源
最近更新 更多