Pythonic填充numpy数组的方法

2024-05-14 17:46:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现自己正在使用csv读取器和for循环遍历每一行来解析大量数据文件(通常是在.csv文件或类似文件中)。例如,数据通常是一个浮动表。

reader = csv.reader(open('somefile.csv'))
header = reader.next()

res_list = [list() for i in header]    

for line in reader:
  for i in range(len(line)):
    res_list[i].append(float(line[i]))

result_dict = dict(zip(header,res_list)) #so we can refer by column title

这是一种很好的填充方式,因此我将每一列作为一个单独的列表进行填充。但是,我更希望项目列表(和嵌套列表)的默认数据容器是numpy数组,因为100个数字中有99个是numpy数组的一倍,这些数字被注入到各种处理脚本/函数中,并且拥有numpy列表的能力使我的生活更轻松。

numpyappend(arr, item)没有附加到位,因此需要为表中的每个点重新创建数组(这很慢而且不必要)。我还可以遍历数据列的列表,并在完成后将它们包装成一个数组(这就是我一直在做的事情),但有时当我完成对文件的分析时,对并不是那么清楚,而且可能需要在以后的行中将内容追加到列表中。

我想知道是否有一些不那么麻烦的方法(使用过度使用的短语“pythonic”)来以类似的方式处理数据表,或者动态地填充数组(底层容器是一个列表),而不总是复制数组。

(另一个注意事项是:通常人们使用列来组织数据,但如果读取器包含read_column参数,则csv将以行方式读取(是的,我知道这样做不会非常高效),我认为许多人会避免使用上面这样的锅炉板代码来解析csv数据文件。)


Tags: 文件csv数据innumpy列表for方式
3条回答

为了有效地将数据加载到NumPyarraya,我喜欢NumPy的fromiter函数。

在这方面的优势:

  • 流式加载

  • 预先指定reesult数组的数据类型,然后

  • 预分配输出数组,然后填充 从iterable来的溪流。

第一个是固有的--fromiter只接受iterable形式的数据输入--最后两个是通过传递给fromiter的第二个和第三个参数,dtype,count来管理的。

>>> import numpy as NP
>>> # create some data to load:
>>> import random
>>> source_iterable = (random.choice(range(100)) for c in range(20))

>>> target = NP.fromiter(source_iterable, dtype=NP.int8, count=v.size)
>>> target
      array([85, 28, 37,  4, 23,  5, 47, 17, 78, 40, 28,  5, 69, 47, 15, 92, 
             41, 33, 33, 98], dtype=int8)

如果不想使用iterable加载数据,您仍然可以使用NumPy函数emptyempty like为目标数组预先分配内存

>>> source_vec = NP.random.rand(10)
>>> target = NP.empty_like(source_vec)
>>> target[:] = source_vec
>>> target
  array([ 0.5472,  0.5085,  0.0803,  0.4757,  0.4831,  0.3054,  0.1024,  
          0.9073,  0.6863,  0.3575])

或者,可以通过调用empty创建一个空的(预先分配的)数组,然后传入所需的形状。此函数与类似于空的相反,让我们传入数据类型:

>>> target = NP.empty(shape=s.shape, dtype=NP.float)
>>> target
  array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])
>>> target[:] = source
>>> target
  array([ 0.5472,  0.5085,  0.0803,  0.4757,  0.4831,  0.3054,  0.1024,  
          0.9073,  0.6863,  0.3575])

我认为很难在现有的基础上有很大的改进。Python列表的构建和附加成本相对较低;NumPy数组的创建成本较高,根本不提供.append()方法。所以你最好的办法就是像你已经在做的那样建立列表,然后在时机成熟时强制使用np.array()

几个小问题:

  • 使用[]创建列表比调用list()稍快。这是程序运行时的一小部分,您可以随意忽略这一点。

  • 当您不实际使用循环索引时,可以使用_作为变量名来记录这一点。

  • 对序列进行迭代通常比找到序列的长度、构建一个range()然后对序列进行大量索引要好。如果还需要索引,可以使用enumerate()获取索引。

把这些放在一起,我认为这是一个稍微改进的版本。但和你的原作几乎没有变化,我想不出有什么好的改进。

reader = csv.reader(open('somefile.csv'))
header = reader.next()

res_list = [ [] for _ in header]

for row in reader:
    for i, val in enumerate(row):
        res_list[i].append(float(val))

# build dict so we can refer by column title
result_dict = dict((n, res_list[i]) for i, n in enumerate(header))

numpy.loadtxt

X = numpy.loadtxt('somefile.csv', delimiter=',')

Documentation.


编辑:对于numpy数组列表

X = [scipy.array(line.split(','), dtype='float') 
     for line in open('somefile.csv', 'r')]

相关问题 更多 >

    热门问题