我正在尝试读取一个看起来像这样的文件:
1, 2,
3, 4,
我正在使用以下行:
l1,l2 = numpy.loadtxt('file.txt',unpack=True,delimiter=', ')
这给了我一个错误,因为每行中的结束逗号被汇总在一起作为最后一个元素(例如“2”被读作“2”)。有没有办法忽略每行中的最后一个逗号,使用loadtxt或其他函数?
答案 0 :(得分:6)
numpy.genfromtxt
更健壮一点。如果您使用默认的dtype(import tkinter as tk
root = tk.Tk()
root.withdraw()
answer = tk.messagebox.askyesno('Confirm', 'Save file?')
# do work here ...
root.destroy() # <-- do I need this?
),则认为存在缺少值的第三列,因此它会创建包含np.float64
的第三列。如果你给它nan
(告诉它从文件中找出数据类型),它会返回包含全零的第三列。无论哪种方式,您都可以使用dtype=None
忽略最后一列:
usecols=[0, 1]
重要提示:我使用的是In [14]: !cat trailing_comma.csv
1, 2,
3, 4,
,而不是delimiter=','
。
delimiter=', '
答案 1 :(得分:3)
usecols
也适用于loadtxt
:
模拟文本分为行的文件:
In [162]: txt=b"""1, 2,
3,4,"""
In [163]: txt=txt.splitlines()
In [164]: txt
Out[164]: [b'1, 2,', b'3,4,']
In [165]: x,y=np.loadtxt(txt,delimiter=',',usecols=[0,1],unpack=True)
In [166]: x
Out[166]: array([ 1., 3.])
In [167]: y
Out[167]: array([ 2., 4.])
loadtxt
和genfromtxt
与多字符分隔符不兼容。
loadtxt
和genfromtxt
接受任何迭代,包括生成器。因此,您可以打开文件并逐个处理这些行,删除多余的字符。
In [180]: def g(txt):
.....: t = txt.splitlines()
.....: for l in t:
.....: yield l[:-1]
In [181]: list(g(txt))
Out[181]: [b'1, 2', b'3,4']
一个生成行的生成器,剥离最后一个字符。这可以更改为逐行读取文件:
In [182]: x,y=np.loadtxt(g(txt),delimiter=',',unpack=True)
In [183]: x,y
Out[183]: (array([ 1., 3.]), array([ 2., 4.]))
答案 2 :(得分:1)
根据您的需要,此解决方案可能过度,但是当处理来自外部源(特别是excel,还有二进制,csv,tsv或其他)的大量数据文件时,我发现pandas
模块是一种非常方便有效的数据读取和处理方式。
给定具有以下内容的数据文件test-data.txt
1, 2,
2, 3,
4, 5,
您可以使用
阅读该文件import pandas as pd
data = pd.read_csv("test-data.txt", names = ("col1", "col2"), usecols=(0,1))
in[25]: data
Out[25]:
col1 col2
0 1 2
1 2 3
2 4 5
In[26]: data.col1
Out[26]:
0 1
1 2
2 4
结果是DataFrame
对象,其索引行和列标签可用于数据访问。如果您的数据文件包含标题,则它直接用于标记列。否则,您可以使用names
参数为每列指定标签。 usecols
参数允许避免第3列,否则将被读取为具有nan
值的列。
答案 3 :(得分:0)
在Python中滚动自己的文件阅读器相当容易,而不必依赖numpy.loadtxt
的约束:
content = [ [ float( x ) for x in row.split(',') if x.strip() ] for row in open( filename, 'rt' ) ]