将文件中单独列的数据保存到Python 2.7中的变量中

时间:2013-06-09 09:31:02

标签: python file-io python-2.7

所以我在文件中有一个样本数据,其安排如下:

  u   v   w   p
 100 200 300 400 
 101 201 301 401
 102 202 302 402
 103 203 303 403 
 104 204 304 404
 105 205 305 405
 106 206 306 406
 107 207 307 407

现在我想阅读第1列并将其保存到列表'u'中,将第2列保存到列表'v'中,依此类推每列直到'p'。 这就是我到目前为止所做的:

import numpy as np
u  = []
v  = []
w  = []
p  = []

with open('testdata.dat') as f:
   for line in f:
       for x in line.split():
           u.append([int(x)])
           v.append([int(x)+1])
           w.append([int(x)+2])
           p.append([int(x)+3]) 

print 'u is'
print(u)
print 'v is'
print(v)
print 'w is'
print(w)
print 'p is'
print(p)

我试过改变索引,但显然它是错误的,因为我得到了输出

u is
[[100], [200], [300], [400], [101], [201], [301], [401], [102], [202], [302], 
 [402], [103], [203], [303], [403], [104], [204], [304], [404], [105], [205], 
 [305], [405], [106], [206], [306], [406], [107], [207], [307], [407]]

v is
[[101], [201], [301], [401], [102], [202], [302], [402], [103], [203], [303], 
 [403], [104], [204], [304], [404], [105], [205], [305], [405], [106], [206], 
 [306], [406], [107], [207], [307], [407], [108], [208], [308], [408]]

w is
[[102], [202], [302], [402], [103], [203], [303], [403], [104], [204], [304], 
 [404], [105], [205], [305], [405], [106], [206], [306], [406], [107], [207], 
 [307], [407], [108], [208], [308], [408], [109], [209], [309], [409]]

p is
[[103], [203], [303], [403], [104], [204], [304], [404], [105], [205], [305], 
 [405], [106], [206], [306], [406], [107], [207], [307], [407], [108], [208], 
 [308], [408], [109], [209], [309], [409], [110], [210], [310], [410]]

它只是通过索引递增行号并读取整行,而我想要 来自每列写入单独变量的数据,即对应于样本数据中给出的名称 - u = 100 - > 107,v = 200 - > 207等。

有关如何在Python中执行此操作的任何想法? (我必须以迭代的方式对真正的大型数据集执行此操作,因此快速有效的代码将会带来很大的好处)

3 个答案:

答案 0 :(得分:2)

请更改内循环:

   for x in line.split():
       u.append([int(x)])
       v.append([int(x)+1])
       w.append([int(x)+2])
       p.append([int(x)+3]) 

   x = line.split()
   u.append([int(x[0])])
   v.append([int(x[1])])
   w.append([int(x[2])])
   p.append([int(x[3])])

在你的原始实现中,循环中的语句“for x in line.split():”将执行四次(对于每一列)。

答案 1 :(得分:1)

x.append([int(y)+c])附加一个元素列表 - int(y)+c

您需要x.append(int(y)+c)来获取数字列表而不是单身人士列表

这里也是非常好的解决方案

from itertools import izip

a="""1 2 3 4
10 20 30 40"""

lines= ([int(y) for y in x.split()] for x in a.split("\n"))
cols = izip(*lines)

print list(cols)

打印

[(1, 10), (2, 20), (3, 30), (4, 40)]

a.split("\n")在您的情况下为open("data").readlines()左右

这应该会给你更好的内存性能,因为你需要在任何给定的时间内只加载一行数据文件,除非你要将生成器转换成列表来继续计算。

但是,我不知道它在CPU方面的性能如何,但我的猜测是它可能会比你的原始代码更好或更好。

如果您要对此进行基准测试,那么仅使用列表而不是生成器并在pypy上尝试它会很有趣(因为https://bitbucket.org/pypy/pypy/wiki/JitFriendliness看到生成器标题)如果您可以将其放入内存中。

考虑您的数据集

  (10**4 * 8 * 12)/1024.0

假设你的数字相对较小并且每个都需要12个字节(Python: How much space does each element of a list take?),这给了我一些不到1MB内存的东西来同时保存所有数据。就内存消耗而言,这是非常小的数据集。

答案 2 :(得分:1)

如果我理解得很清楚,通过使用Python内置函数zipmap,您只需要一行来完成:

from itertools import izip

u,v,w,p = izip(*(map(int,line.split()) for line in open('data.txt')))

# Usage (Python3 syntax)
print("u is", list(u))
print("v is", list(v))
print("w is", list(w))
print("p is", list(p))

产生以下结果:

u is [100, 101, 102, 103, 104, 105, 106, 107]
v is [200, 201, 202, 203, 204, 205, 206, 207]
w is [300, 301, 302, 303, 304, 305, 306, 307]
p is [400, 401, 402, 403, 404, 405, 406, 407]

由于这是您的关注,使用zipmap进行隐式循环应该表现出更好的性能,即在python中进行循环(即使循环非常快)。我不确定这个解决方案是否有更好的内存占用...

编辑:zip替换为izip即使在python 2.x上使用生成器