genfromtxt加载按行排列的数据

时间:2014-06-10 18:35:44

标签: python numpy matplotlib

我有以下格式的数据csv文件:

130, 706, 249, 627, 428, 767, 430,  63, 884, 593
964, 340, 848, 607, 142, 517, 294, 453, 398, 236, 314, 653, 211, 439, 226

有没有办法加载这些数据,以便最终数组包含文件中数据的转置版本,最短列的末尾(即数据文件中的最短行)包含nan值?

最终结果应如下:

array([[130, 964],
[706, 340],
[249, 848],
[627, 607],
[428, 142],
[767, 517],
[430, 294],
[63, 453],
[884, 398],
[593, 236],
[np.nan, 314], 
[np.nan, 653],
[np.nan, 211],
[np.nan, 439],
[np.nan, 226]])

2 个答案:

答案 0 :(得分:2)

您可以使用itertools.izip_longest

from itertools import izip_longest

gen = (line.strip().split(',') for line in open('test.txt'))
np.float_(list(izip_longest(*gen, fillvalue=np.nan)))

给出:

array([[ 130.,  964.],
       [ 706.,  340.],
       [ 249.,  848.],
       [ 627.,  607.],
       [ 428.,  142.],
       [ 767.,  517.],
       [ 430.,  294.],
       [  63.,  453.],
       [ 884.,  398.],
       [ 593.,  236.],
       [  nan,  314.],
       [  nan,  653.],
       [  nan,  211.],
       [  nan,  439.],
       [  nan,  226.]])

答案 1 :(得分:0)

如果您的文件中有逗号分隔的空字段会更容易,例如:

130, 706, 249, 627, 428, 767, 430,  63, 884, 593,    ,    ,    ,    ,
964, 340, 848, 607, 142, 517, 294, 453, 398, 236, 314, 653, 211, 439, 226

然后你就能做到:

>>> np.genfromtxt('csv.csv', delimiter=',', unpack=True)
array([[ 130.,  964.],
       [ 706.,  340.],
       [ 249.,  848.],
       [ 627.,  607.],
       [ 428.,  142.],
       [ 767.,  517.],
       [ 430.,  294.],
       [  63.,  453.],
       [ 884.,  398.],
       [ 593.,  236.],
       [  nan,  314.],
       [  nan,  653.],
       [  nan,  211.],
       [  nan,  439.],
       [  nan,  226.]])

请注意,这是一个float数组。看起来你不能在整数数组中有nan个。您可以使用蒙版数组:

np.ma.masked_equal(
      np.genfromtxt('csv.csv', delimiter=',', dtype=int, unpack=True),
      -1)

因此,预处理文件可能更容易(如果您知道列数):

with open('csv.csv') as fin, open('new.csv', 'w') as fout:
    for line in fin:
        fout.write(line.replace('\n', ',' * (14 - line.count(',')) + '\n'))

其中14是列数减1。