Python 使用不同的条件读取文本文件
我想读取一个arff文件,并将属性和数据分离到不同的列表中。这个文件是。我尝试了以下代码Python 使用不同的条件读取文本文件,python,file-io,Python,File Io,我想读取一个arff文件,并将属性和数据分离到不同的列表中。这个文件是。我尝试了以下代码 from itertools import dropwhile attributes = [] with open('balloons.arff', 'r') as f: for l in f.readlines(): ##1 items = l.split(' ')
from itertools import dropwhile
attributes = []
with open('balloons.arff', 'r') as f:
for l in f.readlines(): ##1
items = l.split(' ') ##2
if items[0] == '@attribute': ##3
attributes.append(items[1]) ##4
data = dropwhile(lambda _line: "@data" not in _line, f) ##5
next(data,"") ##6
for line in data: ##7
print(line.strip()) ##8
print(attributes) ##9
当我运行这段代码时,我只得到属性列表,但是当我注释行号###1到##4(第一个为循环)时,程序正确地给出了数据部分。我有非常大的文件,一个有效的解决方案将受到赞赏。第5行到第9行不再是for循环的一部分,因此“f”没有定义我猜第5行到第9行不再是for循环的一部分,因此“f”没有定义我猜没有必要重新发明轮子。其他人已经为Python编写了ARFF解析器。使用
pip安装它
:
pip install liac-arff
然后导入并使用模块:
import arff
with open('balloons-adult-stretch.arff', 'rb') as handle:
data = arff.load(handle)
print(data['attributes'])
print(data['data'])
输出:
[(u'V1', [u'PURPLE', u'YELLOW']), (u'V2', [u'LARGE', u'SMALL']), (u'V3', [u'DIP', u'STRETCH']), (u'V4', [u'ADULT', u'CHILD']), (u'Class', [u'1', u'2'])]
[[u'YELLOW', u'SMALL', u'STRETCH', u'ADULT', u'2'], [u'YELLOW', u'SMALL', u'STRETCH', u'CHILD', u'2'], [u'YELLOW', u'SMALL', u'DIP', u'ADULT', u'2'], [u'YELLOW', u'SMALL', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'SMALL', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'LARGE', u'STRETCH', u'ADULT', u'2'], [u'YELLOW', u'LARGE', u'STRETCH', u'CHILD', u'2'], [u'YELLOW', u'LARGE', u'DIP', u'ADULT', u'2'], [u'YELLOW', u'LARGE', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'LARGE', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'SMALL', u'STRETCH', u'ADULT', u'2'], [u'PURPLE', u'SMALL', u'STRETCH', u'CHILD', u'2'], [u'PURPLE', u'SMALL', u'DIP', u'ADULT', u'2'], [u'PURPLE', u'SMALL', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'SMALL', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'LARGE', u'STRETCH', u'ADULT', u'2'], [u'PURPLE', u'LARGE', u'STRETCH', u'CHILD', u'2'], [u'PURPLE', u'LARGE', u'DIP', u'ADULT', u'2'], [u'PURPLE', u'LARGE', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'LARGE', u'DIP', u'CHILD', u'1']]
如果您确实希望自己编写此代码,那么代码的问题在于第一个循环读取文件中的所有行。在循环结束后,您必须使用
f.seek(0)
将文件句柄倒回开头,或者通过实现一个简单的状态机一次性解析它:
attributes = {}
data = []
reading_data = False
with open('balloons-adult-stretch.arff', 'r') as handle:
for line in handle:
line = line.strip()
# Ignore comments and whitespace
if line.startswith('%%') or not line:
continue
# If we have already reached the @data section, we just read indefinitely
# If @data doesn't come last, this will not work
if reading_data:
data.append(line)
continue
# Otherwise, try parsing the file
if line.startswith('@attribute'):
key, value = line.split(' ', 2)[1:]
attributes[key] = value
elif line.startswith('@data'):
reading_data = True
else:
#raise ValueError('Cannot parse line {!r}'.format(line))
pass
没有必要重新发明轮子。其他人已经为Python编写了ARFF解析器。使用
pip安装它
:
pip install liac-arff
然后导入并使用模块:
import arff
with open('balloons-adult-stretch.arff', 'rb') as handle:
data = arff.load(handle)
print(data['attributes'])
print(data['data'])
输出:
[(u'V1', [u'PURPLE', u'YELLOW']), (u'V2', [u'LARGE', u'SMALL']), (u'V3', [u'DIP', u'STRETCH']), (u'V4', [u'ADULT', u'CHILD']), (u'Class', [u'1', u'2'])]
[[u'YELLOW', u'SMALL', u'STRETCH', u'ADULT', u'2'], [u'YELLOW', u'SMALL', u'STRETCH', u'CHILD', u'2'], [u'YELLOW', u'SMALL', u'DIP', u'ADULT', u'2'], [u'YELLOW', u'SMALL', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'SMALL', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'LARGE', u'STRETCH', u'ADULT', u'2'], [u'YELLOW', u'LARGE', u'STRETCH', u'CHILD', u'2'], [u'YELLOW', u'LARGE', u'DIP', u'ADULT', u'2'], [u'YELLOW', u'LARGE', u'DIP', u'CHILD', u'1'], [u'YELLOW', u'LARGE', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'SMALL', u'STRETCH', u'ADULT', u'2'], [u'PURPLE', u'SMALL', u'STRETCH', u'CHILD', u'2'], [u'PURPLE', u'SMALL', u'DIP', u'ADULT', u'2'], [u'PURPLE', u'SMALL', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'SMALL', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'LARGE', u'STRETCH', u'ADULT', u'2'], [u'PURPLE', u'LARGE', u'STRETCH', u'CHILD', u'2'], [u'PURPLE', u'LARGE', u'DIP', u'ADULT', u'2'], [u'PURPLE', u'LARGE', u'DIP', u'CHILD', u'1'], [u'PURPLE', u'LARGE', u'DIP', u'CHILD', u'1']]
如果您确实希望自己编写此代码,那么代码的问题在于第一个循环读取文件中的所有行。在循环结束后,您必须使用
f.seek(0)
将文件句柄倒回开头,或者通过实现一个简单的状态机一次性解析它:
attributes = {}
data = []
reading_data = False
with open('balloons-adult-stretch.arff', 'r') as handle:
for line in handle:
line = line.strip()
# Ignore comments and whitespace
if line.startswith('%%') or not line:
continue
# If we have already reached the @data section, we just read indefinitely
# If @data doesn't come last, this will not work
if reading_data:
data.append(line)
continue
# Otherwise, try parsing the file
if line.startswith('@attribute'):
key, value = line.split(' ', 2)[1:]
attributes[key] = value
elif line.startswith('@data'):
reading_data = True
else:
#raise ValueError('Cannot parse line {!r}'.format(line))
pass
问题是,在for循环中,您已经到达了EOF(文件结尾)。这意味着,一旦启动lambda函数,文件中就没有可读取的内容了。您可以找到一种方法来读取for循环中的数据,或者如果您想(稍微)低效地执行此操作,可以执行以下操作:
from itertools import dropwhile
attributes = []
with open('stuff.txt', 'r') as f:
for l in f.readlines(): ##1
items = l.split(' ') ##2
if items[0] == '@attribute': ##3
attributes.append(items[1])
f.seek(0) ##4
data = dropwhile(lambda _line: "@data" not in _line, f) ##5
next(data,"") ##6
for line in data: ##7
print(line.strip()) ##8
print(attributes)
问题是,在for循环中,您已经到达了EOF(文件结尾)。这意味着,一旦启动lambda函数,文件中就没有可读取的内容了。您可以找到一种方法来读取for循环中的数据,或者如果您想(稍微)低效地执行此操作,可以执行以下操作:
from itertools import dropwhile
attributes = []
with open('stuff.txt', 'r') as f:
for l in f.readlines(): ##1
items = l.split(' ') ##2
if items[0] == '@attribute': ##3
attributes.append(items[1])
f.seek(0) ##4
data = dropwhile(lambda _line: "@data" not in _line, f) ##5
next(data,"") ##6
for line in data: ##7
print(line.strip()) ##8
print(attributes)
我不能在循环中使用它,当我删除缩进时,我得到了错误消息f in not define。所以,我想这不是一个问题。谢谢你的回答对不起,实际上我指的是for循环和“l”;-)所以不要删除,而是添加一个缩进。。。但是@Blender有一个更好的答案;-)我不能在循环中使用它,当我删除缩进时,我得到了错误消息f in not define。所以,我想这不是一个问题。谢谢你的回答对不起,实际上我指的是for循环和“l”;-)所以不要删除,而是添加一个缩进。。。但是@Blender有一个更好的答案;-)非常感谢您的想法和解决方案。我会给arff软件包一些时间。@BlenderI在
attributes[key]=value
处收到错误消息,然后我将其更改为attributes.append(key)
,因为我需要属性名而不是属性值。这是正确的方法吗?@Abrar:如果有效,就有效。您也可以只使用attributes.keys()
并将其作为字典。非常感谢您的想法和解决方案。我会给arff软件包一些时间。@BlenderI在attributes[key]=value
处收到错误消息,然后我将其更改为attributes.append(key)
,因为我需要属性名而不是属性值。这是正确的方法吗?@Abrar:如果有效,就有效。您也可以只使用attributes.keys()
并将其作为字典。