所以我在文件中有一个样本数据,其安排如下:
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中执行此操作的任何想法? (我必须以迭代的方式对真正的大型数据集执行此操作,因此快速有效的代码将会带来很大的好处)
答案 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内置函数zip
和map
,您只需要一行来完成:
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]
由于这是您的关注,使用zip
和map
进行隐式循环应该表现出更好的性能,即在python中进行循环(即使循环非常快)。我不确定这个解决方案是否有更好的内存占用...
编辑:将zip
替换为izip
即使在python 2.x上使用生成器