【问题标题】:Converting a list of strings in a numpy array in a faster way以更快的方式转换 numpy 数组中的字符串列表
【发布时间】:2011-11-07 18:27:39
【问题描述】:

br 是字符串列表的名称,如下所示:

['14 0.000000 -- (long term 0.000000)\n',
 '19 0.000000 -- (long term 0.000000)\n',
 '22 0.000000 -- (long term 0.000000)\n',
...

我对前两列感兴趣,我想将其转换为 numpy 数组。 到目前为止,我提出了以下解决方案:

x = N.array ([0., 0.])
for i in br:
    x = N.vstack ( (x, N.array (map (float, i.split ()[:2]))) )

这会产生一个二维数组:

array([[  0.,   0.],
       [ 14.,   0.],
       [ 19.,   0.],
       [ 22.,   0.],
...

但是,由于br 相当大(~10^5 个条目),此过程需要一些时间。 我想知道,有没有办法在更短的时间内完成相同的结果?

【问题讨论】:

    标签: python string list numpy


    【解决方案1】:

    这对我来说要快得多:

    import numpy as N
    
    br = ['14 0.000000 -- (long term 0.000000)\n']*50000
    aa = N.zeros((len(br), 2))
    
    for i,line in enumerate(br):
        al, strs = aa[i], line.split(None, 2)[:2]
        al[0], al[1] = float(strs[0]), float(strs[1])
    

    变化:

    • 预分配 numpy 数组(这很大)。您已经知道您需要一个具有特定维度的二维数组。
    • 仅对前 2 列进行 split(),因为您不需要其他列。
    • 不要使用 map():它比列表推导要慢。我什至没有使用列表推导,因为你知道你只有 2 列。
    • 直接分配到预先分配的数组中,而不是在迭代时生成新的临时数组。

    【讨论】:

    • aa = numpy.array([x.split(' ',2)[0:2] for x in br], dtype='float')
    • 很高兴知道enumerate:我不知道!还要感谢@steabert 的贡献。这两种解决方案的速度对我来说似乎非常相似。
    【解决方案2】:

    如果字符串列表来自文件,您可以尝试预处理(以 awk 为例),并使用 numpy.fromtxt。 如果您对获取此列表的方式无能为力,您有几种可能:

    • 放弃吧。您将每天运行一次此功能。你不关心速度,你的实际解决方案就足够了
    • 用 cython 编写一个 IO 插件。您有很大的潜在收益,因为您将能够在 c 中执行所有循环,并直接影响大 (10^5, 2) numpy ndarray 中的值
    • 尝试另一种语言来解决您的问题。如果使用 c 或 haskell 等语言,您可以使用 ctypes 从 python 调用在 dll 中编译的函数

    编辑

    也许这种方法稍微快一点:

    def conv(mysrt):
        return map(float, mystr.split()[:2])
    
    br_float = map(conv, br)
    x = N.array(br_float)
    

    【讨论】:

    • 喜欢“开箱即用”的想法!
    【解决方案3】:

    变化

    map (float, i.split()[:2])
    

    map (float, i.split(' ',2)[:2])
    

    可能会导致轻微的加速。由于您只关心每行中的前两个空格分隔的项目,因此无需拆分整行。 i.split(' ',2) 中的 2 告诉 split 最多只进行 2 次拆分。例如,

    In [11]: x='14 0.000000 -- (long term 0.000000)\n' 
    
    In [12]: x.split()
    Out[12]: ['14', '0.000000', '--', '(long', 'term', '0.000000)']
    
    In [13]: x.split(' ',2)
    Out[13]: ['14', '0.000000', '-- (long term 0.000000)\n']
    

    【讨论】:

    • 感谢split的第二个参数的解释!
    猜你喜欢
    • 2019-03-24
    • 1970-01-01
    • 2023-03-12
    • 2016-06-06
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    相关资源
    最近更新 更多