2014-09-28 13 views
0

我有一个看起来有点像这样的输入文件:阅读不同尺寸的行转换成列在python

0.1 0.3 0.4 0.3 
0.2 02. 1.2 -0.2 
0.1 -1.22 0.12 9.2 0.2 0.2 
0.3 -1.42 0.2 6.2 0.9 0.88 
0.3 -1.42 0.12 1.1 0.1 0.88 0.06 0.14 
4 

所以一些列数开始,以N * 2列结束(n是最后一行)。 我可以得到行数,说#行=我。我也可以得到n。 我想将这个文件读入python 2d数组(不是列表),例如阵列[I] [N * 2]。我意识到我可能需要用零来填补空列,以便它可以简单地理解为

Array = numpy.loadtxt("data.txt") 

但我不知道如何着手。

感谢

+0

我认为我理解你想要的东西,直到你说'Array [i] [n * 2]'。这看起来像是一维数组的一维数组。一个二维数组被标记为'a [i,j]',并且它的形状类似于'(i,n * 2)'。那是你想要的吗? – abarnert 2014-09-28 02:46:04

+0

是的,对不起,我很困惑C++语法与python语法 – Jesus 2014-09-28 03:40:23

+0

这不仅仅是语法问题。 C++根本就没有2D数组;它有数组数组(当然,它有1D N * M数组,你可以手动跨步)。如果你真的想要像C++数组数组一样,首先你不会有这个问题,因为数组数组不一定是矩形,而是二维数组。 – abarnert 2014-09-28 07:03:11

回答

2

我不认为任何内置的缺失值的东西是要在这里帮忙的,因为空间分隔柱,使它成为暧昧其值丢失。 (在你的上下文中不含糊不清 - 你知道所有缺失的列在右边 - 但通用解析器不会。)希望我错了,别人会提供一个更简单的答案,否则...

一种选择是逐行扩展行并将它们输入到数组中。

def readrow(row, cols): 
    a = np.fromstring(row, sep=' ') 
    a.resize((cols,) 
    return a 

with open(file_path, 'rb') as f: 
    a = np.array([readrow(row, 2*n) for row in f]) 

如果你不能浪费创建i一维数组的临时列表中的内存,您可能需要:如果内存是不是一个问题,你可以用一个列表理解了该行做到这一点使用类似fromiter产生一维数组,然后重新塑造它:

a = np.fromiter(itertools.chain.from_iterable(
    readrow(row, n*2) for row in f)).reshape((n*2,)) 

(虽然在这一点上,使用numpy的解析,而不是csv或只是str.split好像它可能是一个有点傻行)

+0

我认为这是一个非常好的答案。但我可以挑剔,但是:'fname'实际上是'fpath',我不明白为什么'rb'模式是必要的,因为输入文件显然是一个文本文件。因此,我会做一个简单的'open(fpath)'。还有最后一行的问题,它显然包含原始问题中的'n',不应该放在数组中,但让我们看看耶稣说了些什么。 – EOL 2014-09-28 04:28:44

+0

这里没有任何答案真的有帮助。这个答案看起来很有希望,但是当我尝试实现它时,它会给出错误“无效模式('rb')或文件名”,这很奇怪,因为我没有包含'rb',并且我有另外一行与open声明/文件。 我已经把它归结为:如何将列表的值复制到更大的numpy数组。将list = [1 2 3 4 5]复制到所有条目为零的Array [10]中。如何将列表复制到数组中的前5个元素,并将它们留在零处。谢谢 – Jesus 2014-09-28 05:12:07

+0

@EOL:'fname'就是提问者代码中的任何内容,他并没有给我们提供。 'rb'模式是必须的,因为'np.fromstring'是因为在3.x中它需要'bytes',而不是'str';如果你切换到'csv',它在3.x中将不再是必需的,而是在2.x中。无论哪种方式,它永远不会伤害。最后一行包含原始问题的'n',因为他说他可以独立地获得'i'和'n',所以我假设我不需要编写代码来获取它们。 – abarnert 2014-09-28 06:59:03

0

个如果要垫短线0.0的下面是一个办法 - 垫满= 0.0的,那么只切片领先显著部分:

data = """0.1 0.3 0.4 0.3 
0.2 02. 1.2 -0.2 
0.1 -1.22 0.12 9.2 0.2 0.2 
0.3 -1.42 0.2 6.2 0.9 0.88 
0.3 -1.42 0.12 1.1 0.1 0.88 0.06 0.14 
4""".splitlines() 

maxcols = int(data[-1])*2 

emptyvalue = 0.0 
pad = [emptyvalue]*maxcols 

for line in data[:-1]: 
    # get the input data values, converted from strings to floats 
    vals = map(float, line.split()) 

    # pad the input with default values, then only take the first maxcols values 
    vals = (vals + pad)[:maxcols] 

    # show our work in a nice table 
    print "[" + ','.join("%s%.2f" % (' ' if v>=0 else '', v) for v in vals) + "]" 

打印

[ 0.10, 0.30, 0.40, 0.30, 0.00, 0.00, 0.00, 0.00] 
[ 0.20, 2.00, 1.20,-0.20, 0.00, 0.00, 0.00, 0.00] 
[ 0.10,-1.22, 0.12, 9.20, 0.20, 0.20, 0.00, 0.00] 
[ 0.30,-1.42, 0.20, 6.20, 0.90, 0.88, 0.00, 0.00] 
[ 0.30,-1.42, 0.12, 1.10, 0.10, 0.88, 0.06, 0.14]