我使用Python生成由很长的行组成的ASCII文件.这是一个示例行(假设文件中的第100行,'[...]'由我添加以缩短行):
{6 1,14 1,[...],264 1,270 2,274 2,[...],478 1,479 8,485 1,[...]}
Run Code Online (Sandbox Code Playgroud)
如果我打开使用ipython生成的ASCII文件:
f = open('myfile','r')
print repr(f.readlines()[99])
Run Code Online (Sandbox Code Playgroud)
我确实获得了正确打印的预期行('[...]'由我添加以缩短行):
'{6 1,14 1,[...],264 1,270 2,274 2,[...],478 1,479 8,485 1,[...]}\n'
Run Code Online (Sandbox Code Playgroud)
相反,如果我用想要读取它的程序打开这个文件,它会产生一个异常,在478之后抱怨意外的一对1.所以我试着用vim打开文件.仍然vim显示没有问题,但如果我复制vim打印的行并将其粘贴到另一个文本编辑器(在我的案例中为TextMate),这就是我获得的行('[...]'由我添加到缩短线):
{6 1,14 1,[...],264 1,270 2,274 2,[...],478 1,4 79 8,485 1,[...]}
Run Code Online (Sandbox Code Playgroud)
这一行确实在对478之后出现了问题1.我尝试以不同的方式生成我的行(连接,使用cStringIO,...),但我总是得到这个结果.例如,当使用cStringIO时,生成的行如下所示(尽管我试图改变它,但没有运气):
def _construct_arff(self,attributes,header,data_rows):
"""Create the string representation of a Weka ARFF file.
*attributes* is a dictionary with attribute_name:attribute_type
(e.g., 'num_of_days':'NUMERIC')
*header* is a list of the attributes sorted
(e.g., ['age','name','num_of_days'])
*data_rows* is a list of lists with the values, sorted as in the header
(e.g., [ [88,'John',465],[77,'Bob',223]]"""
arff_str = cStringIO.StringIO()
arff_str.write('@relation %s\n' % self.relation_name)
for idx,att_name in enumerate(header):
try:
name = att_name.replace("\\","\\\\").replace("'","\\'")
arff_str.write("@attribute '%s' %s\n" % (name,attributes[att_name]))
except UnicodeEncodeError:
arff_str.write('@attribute unicode_err_%s %s\n'
% (idx,attributes[att_name]))
arff_str.write('@data\n')
for data_row in data_rows:
row = []
for att_idx,att_name in enumerate(header):
att_type = attributes[att_name]
value = data_row[att_idx]
# numeric attributes can be sparse: None and zeros are not written
if ((not att_type == constants.ARRF_NUMERIC)
or not ((value == None) or value == 0)):
row.append('%s %s' % (att_idx,value))
arff_str.write('{' + (','.join(row)) + '}\n')
return arff_str.getvalue()
Run Code Online (Sandbox Code Playgroud)
更新:从上面的代码中可以看出,该函数将给定的数据集转换为特殊的arff文件格式.我注意到我创建的一个属性包含数字作为字符串(例如,'1',而不是1).通过强制这些数字为整数:
features[name] = int(value)
Run Code Online (Sandbox Code Playgroud)
我成功地重新创建了arff文件.但是我不知道这是一个值,它是如何对*att_idx*的格式产生影响的,它总是一个整数,同样由@JohnMachin和@gnibbler指出(感谢您的答案,顺便说一句) .所以,即使我的代码现在运行,我仍然不明白为什么会发生这种情况.如果没有正确转换为int,该值如何影响其他内容的格式?
此文件包含格式错误的版本.
Joh*_*hin 11
内置函数repr是你的朋友.它会毫不含糊地向您显示文件中的内容.
做这个:
f = open('myfile','r')
print repr(f.readlines()[99])
Run Code Online (Sandbox Code Playgroud)
并编辑您的问题以显示结果.
更新:关于它是如何实现的,无法分辨,因为它不能由您展示的代码生成.该值37
应该是att_idx的值,enumerate()
因此必须是int.你用%s格式化这个int ... 37不能成为3rubbish7
.此外,应该按0,1等等生成att_idx但是你缺少很多值,你的循环中没有任何条件.
请告诉我们您实际运行的代码.
更新:
而且,此代码将无法运行:
for idx,att_name in enumerate(header):
arff_str.write("@attribute '%s' %s\n" % (name,attributes[att_name]))
Run Code Online (Sandbox Code Playgroud)
因为name
没有定义; 你可能意味着att_name
.
也许我们可以将所有这些内容短路:在网络上的某个地方发布你的输出文件的副本(如果它很大,则压缩),这样我们就可以看到可能会扰乱其消费者的内容.请编辑您的问题,以说明问题出在哪条线上.
顺便说一下,你说一些数据是字符串而不是整数,如果你int
通过这样做来强制数据,问题就会消失features[name] = int(value)
......什么是"特征"?什么名字'??
这些字符串中的任何一个都不unicode
是str
吗?
更新2(在网上发布错误文件后)
没有提供关于哪一行显示问题的信息.事实证明,没有任何行显示属性479所描述的问题.我写了这个检查脚本:
import re, sys
# sample data line:
# {40 1,101 3,319 2,375 2,525 2,530 bug}
# Looks like all data lines end in ",530 bug}" or ",530 other}"
pattern1 = r"\{(?:\d+ \d+,)*\d+ \w+\}$"
matcher1 = re.compile(pattern1).match
pattern2 = r"\{(?:\d+ \d+,)*"
matcher2 = re.compile(pattern2).match
bad_atts = re.compile(r"\D\d+\s+\W").findall
got_data = False
for lino, line in enumerate(open(sys.argv[1], "r"), 1):
if not got_data:
got_data = line.startswith('@data')
continue
if not matcher1(line):
print
print lino, repr(line)
m = matcher2(line)
if m:
print "OK up to offset", m.end()
print bad_atts(line)
Run Code Online (Sandbox Code Playgroud)
样本输出(包含在第80列):
581 '{2 1,7 1,9 1,12 1,13 1,14 1,15 1,16 1,17 1,18 1,21 1,22 1,24 1,25 1,26 1,27
1,29 1,32 1,33 1,36 1,39 1,40 1,44 1,48 1,49 1,50 1,54 1,57 1,58 1,60 1,67 1,68
1,69 1,71 1,74 1,75 1,76 1,77 1,80 1,88 1,93 1,101 ,103 6,104 2,109 20,110 3,11
2 2,114 1,119 17,120 4,124 39,128 5,137 1,138 1,139 1,162 1,168 1,172 18,175 1,1
76 6,179 1,180 1,181 2,185 2,187 9,188 8,190 1,193 1,195 2,196 4,197 1,199 3,201
3,202 4,203 5,206 1,207 2,208 1,210 2,211 1,212 5,213 1,215 2,216 3,218 2,220 2
,221 3,225 8,226 1,233 1,241 4,242 1,248 5,254 2,255 1,257 4,258 4,260 1,266 1,2
68 1,269 3,270 2,271 5,273 1,276 1,277 1,280 1,282 1,283 11,285 1,288 1,289 1,29
6 8,298 1,299 1,303 1,304 11,306 5,308 1,309 8,310 1,315 3,316 1,319 11,320 5,32
1 11,322 2,329 1,342 2,345 1,349 1,353 2,355 2,358 3,359 1,362 1,367 2,368 1,369
1,373 2,375 9,377 1,381 4,382 1,383 3,387 1,388 5,395 2,397 2,400 1,401 7,407 2
,412 1,416 1,419 2,421 2,422 1,425 2,427 1,431 1,433 7,434 1,435 1,436 2,440 1,4
49 1,454 2,455 1,460 3,461 1,463 1,467 1,470 1,471 2,472 7,477 2,478 11,479 31,4
82 6,485 7,487 1,490 2,492 16,494 2,495 1,497 1,499 1,501 1,502 1,503 1,504 11,5
06 3,510 2,515 1,516 2,517 3,518 1,522 4,523 2,524 1,525 4,527 2,528 7,529 3,530
bug}\n'
OK up to offset 203
[',101 ,']
709 '{101 ,124 2,184 1,188 1,333 1,492 3,500 4,530 bug}\n'
OK up to offset 1
['{101 ,']
Run Code Online (Sandbox Code Playgroud)
所以看起来属性att_idx == 101
有时可以包含空字符串''
.您需要弄清楚如何处理此属性.如果您解开这个拜占庭代码,这将有助于您的思考:
if ((not att_type == constants.ARRF_NUMERIC)
or not ((value == None) or value == 0)):
Run Code Online (Sandbox Code Playgroud)
旁白:"咒骂删除"代码不会运行; 它应该是ARFF,而不是ARRF
成:
if value or att_type != constants.ARFF_NUMERIC:
Run Code Online (Sandbox Code Playgroud)
或者只是if value:
将过滤掉所有的None
,0
和""
.请注意,att_idx == 101
对应于ARFF文件头中给定STRING类型的属性"priority":
[line 103] @attribute 'priority' STRING
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你关于features[name] = int(value)
"解决"这个问题的陈述非常可疑; int("")
提出异常.
它可以帮助您阅读本维基部分末尾有关稀疏ARFF文件的警告.
归档时间: |
|
查看次数: |
221 次 |
最近记录: |