填充numpy数组的Pythonic方法
我发现自己正在使用csv阅读器和for循环对每一行进行迭代,从而解析大量数据文件(通常是.csv文件或类似文件)。例如,数据通常是一个浮动表填充numpy数组的Pythonic方法,python,arrays,numpy,Python,Arrays,Numpy,我发现自己正在使用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(
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数组,因为99次/100次的数字被输入到各种处理脚本/函数中,而numpy列表的强大功能使我的生活更轻松
numpyappend(arr,item)
没有适当地追加,因此需要为表中的每个点重新创建数组(这既慢又不必要)。我也可以迭代数据列列表,并在完成后将它们包装到一个数组中(这就是我一直在做的),但有时我在解析文件时并不是很清楚,而且可能需要在以后将内容添加到列表中
我想知道是否有一些不那么麻烦的方法(使用过度使用的短语“pythonic”)以类似的方式处理数据表,或者动态地填充数组(底层容器是一个列表),而无需一直复制数组
(另一个注意事项是:一般来说,人们使用列来组织数据,但如果读取器合并了read_column参数,则
csv
以行形式读取数据,这有点烦人(是的,我知道这不会非常高效),我想许多人会避免使用上面的锅炉板代码来解析csv数据文件。)有numpy.loadtxt
:
X = numpy.loadtxt('somefile.csv', delimiter=',')
编辑:对于numpy数组的列表
X = [scipy.array(line.split(','), dtype='float')
for line in open('somefile.csv', 'r')]
我认为很难在你现有的基础上提高很多。Python列表的构建和附加成本相对较低;NumPy数组的创建成本更高,而且根本不提供
.append()
方法。因此,最好的办法是像您已经在做的那样构建列表,然后在时机成熟时强制使用np.array()
有几个要点:
- 使用
创建列表比调用[]
稍微快一点。这是程序运行时的一小部分,您可以随意忽略这一点list()
- 当您实际上不使用循环索引时,可以使用变量名
来记录这一点\uu
- 迭代一个序列通常比查找序列的长度、构建一个
,然后对序列进行大量索引要好。如果还需要索引,可以使用范围()
获取索引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))
为了有效地将数据加载到NumPyarraya,我喜欢NumPy的fromiter函数 这方面的优势:
- 流式装载
- 预先指定reesult数组的数据类型,以及
- 预分配空输出数组,然后填充该数组 从伊特拉布河来的小溪
>>> 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])
我以前考虑过这一点,但它有一些问题,特别是它要求数组中的行长度相同。虽然我的小代码片段假设相同,但它并不总是发生(例如,空行表示数据收集突发之间的中断)。“NumPy…根本不提供.append()方法”NumPy确实有一个append方法。它的工作原理与python append差不多,只是没有“就位”。@doug:
a=np.array(范围(3))
成功。然后,a.append(4)
给出消息AttributeError:'numpy.ndarray'对象没有属性'append'
。如果NumPy数组有一个.append()
方法,那么我在这里做错了什么?那么试试这个:a=NP.random.randint(0,10,5);a=NP.append(a[2,3])。所以NumPy有一个append函数而不是append方法——这使得您在上面的答案中的语句完全正确!在回答问题之前,我通常会先尝试一下。但是我没有想到要寻找一个非方法append()
函数!
>>> 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])