Numpy:loadtxt(),列数可变

时间:2016-07-05 10:41:28

标签: numpy

我有一个以制表符分隔的值的文件,其中文件的前半部分有3列N行,后半部分有2列和M行。我需要将这样的文件转换为两个独立的数组:3xN和2xM。

示例:

   6.7900209022264466       -3.8259897286289504        13.563976248832137     
   1.5334543760683907        12.723711617874176        1.5148291755004299     
   2.4282763900233522        9.1305022788201136       -3.1003673775485394     
  -6.5344717544805586E-002  -12.487743380186622        2.6928902187606480     
   8.9067951331740804        13.403331728374390      -0.58045132774289632     
  -11.842481592786449       -5.7083783211328551        1.9526760053685255     
  -10.240286781275808        13.204312088815593        4.4856524683466175     
  -4.6690658488407504       -6.2809313597959449        7.4378900284937082     
  -9.5874077836478282       -8.6799071183782903       -1.8203838010218165     
  0.62588896716878051       -5.4614995295716540        11.166650096421838     
           0        4173
           0        1998
           0         611
           0        8606
           1        6912
           1        9671
           1        7993
           1        8513
           2        5556
           2        4422
           2        3047

我不能简单地使用loadtxt()来阅读此类文件,因为这会导致错误ValueError: Wrong number of columns at line ...

有没有办法使用loadtxt()或类似功能来读取这样的文件?

我想避免使用readlines()split()然后转换为float,因为这会使代码变慢(我认为......)并且更长。我也试过pandas.read_csv(),但我需要一个数组作为输出。

更新

目前,按照 hpaulj 的建议,我使用readlines()split()这样做:

    with open(filename,"r") as f:
        all_data=[x.split() for x in f.readlines()]
        a=array([map(float,x) for x in all_data[:N]])
        b=array([map(int,x) for x in all_data[N+1:]])

它实际上非常快,但我仍然想知道是否有人知道更快 - 也许更简单 - 的方法。

3 个答案:

答案 0 :(得分:0)

我建议使用CompilerMojo,然后使用pandas.read_csv() - see documentation

中的.values属性获取numpy数组
DataFrame

现在,如果您只使用import pandas as pd import numpy as np df = pd.read_csv("filename.txt") array_values = df.values ,那么您将获得.values的缺失值。您可以通过检查包含nan缺失值的索引来确定MN

答案 1 :(得分:0)

您可以使用numpy函数:np.genfromtxt()

import numpy as np

reading = np.genfromtxt("file", delimiter=" ")

您可以发布.txt文件的示例吗?

答案 2 :(得分:0)

不幸的是,使用[x.split() for x in f.readlines()]会将所有行作为字符串对象加载到python列表中,这会很慢,并且比numpy数组需要更多的内存。

假设您已经预先知道分割线(因为您在建议中使用了N),则可以执行以下操作:

from itertools import islice

with open(filename, 'r') as f:
    first_part = numpy.loadtxt(islice(f, N))
    second_part = numpy.loadtxt(f)

islice是一个工具,它将在numpy读取N行后停止生成行。当在同一文件上调用第二个loadtxt时,numpy将从先前停止的位置开始,因此您无需执行其他任何操作。

由于仅使用生成器,因此不需要将所有中间行都存储为字符串。