1

Python を使用して、非常に長い行で構成される ASCII ファイルを生成しています。これは一例の行です (ファイルの 100 行目としましょう。'[...]' は、行を短くするために私が追加したものです):

{6 1,14 1,[...],264 1,270 2,274 2,[...],478 1,479 8,485 1,[...]}

ipython で生成した ASCII ファイルを開くと、次のようになります。

f = open('myfile','r')
print repr(f.readlines()[99])

私は正しく印刷された予想される行を取得します(「[...]」は行を短くするために私が追加しました):

'{6 1,14 1,[...],264 1,270 2,274 2,[...],478 1,479 8,485 1,[...]}\n'

逆に、このファイルを読み取るはずのプログラムでこのファイルを開くと、例外が発生し、478 1 の後に予期しないペアがあると不平を言うので、vimでファイルを開こうとしました。それでもvimは問題を示しませんが、vimによって印刷された行をコピーして別のテキストエディターに貼り付けると(私の場合はTextMate)、これが取得した行です(「[...]」は私によって追加されます行を短くします):

{6 1,14 1,[...],264 1,270      2,274 2,[...],478 1,4     79 8,485 1,[...]}

この行には、ペア 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()

UPDATE : 上記のコードからわかるように、関数は特定のデータ セットを特別な arff ファイル形式に変換します。作成していた属性の 1 つに、数値が文字列として含まれていることに気付きました (たとえば、1 ではなく '1')。これらの数値を整数に強制すると、次のようになります。

features[name] = int(value)

arff ファイルを正常に再作成しました。ただし、@ JohnMachinと@gnibblerによっても指摘されているように、値であるこれが*att_idx *のフォーマットにどのように影響するかはわかりません。これは常に整数です(回答ありがとうございます) . そのため、コードが実行されたとしても、なぜこれが起こるのかわかりません。値がintに適切に変換されていない場合、他のものの書式設定にどのように影響しますか?

このファイルには、間違った形式のバージョンが含まれています。

4

1 に答える 1

11

組み込み関数reprはあなたの味方です。ファイルの内容が明確に表示されます。

これを行う:

f = open('myfile','r')
print repr(f.readlines()[99])

質問を編集して結果を表示します。

更新:あなたが示したコードによって生成されたわけではないため、どのようにしてそこに到達したかを知ることは不可能です. 値は、int である必要が37ある att_idx の値であるenumerate()必要があります。この int を %s でフォーマットしています ... 37 can't be 3rubbish7. また、0、1などの順序でatt_idxを生成する必要がありますが、多くの値が欠落しており、ループ内に条件はありません。

実際に実行したコードを見せてください。

更新

繰り返しますが、このコードは実行されません。

for idx,att_name in enumerate(header):
    arff_str.write("@attribute '%s' %s\n" % (name,attributes[att_name]))

name定義されていないため。あなたはおそらく意味しatt_nameます。

出力ファイルのコピー (サイズが大きい場合は zip 形式) を Web のどこかに投稿して、消費者を混乱させている可能性があるものを自分で確認できるようにします。質問を編集して、どの行が問題を示しているかを教えてください。

ところで、データの一部は整数ではなく文字列だとおっしゃっていますが、データを次のように強制すると問題は解決します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)

出力例 (列 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 ,']

そのため、 の属性にatt_idx == 101は空の文字列が含まれることがあるよう''です。この属性をどのように扱うかを整理する必要があります。このビザンチン コードを解きほぐすと、思考の助けになります。

  if ((not att_type == constants.ARRF_NUMERIC)
      or not ((value == None) or value == 0)):

余談ですが、その「罵倒削除」コードは実行されません。ARRF ではなく、ARFF である必要があります。

の中へ:

if value or att_type != constants.ARFF_NUMERIC:

または、 、、およびif value:のすべてを除外するものだけかもしれません。ARFF ファイル ヘッダーで STRING タイプが指定されている属性「priority」に対応することに注意してください。None0""att_idx == 101

[line 103] @attribute 'priority' STRING

ところで、features[name] = int(value)問題の「修正」に関するあなたの発言は非常に疑わしいものです。int("")例外を発生させます。

スパース ARFF ファイルに関するこの wiki セクションの最後にある警告を読むと役立つ場合があります。

于 2012-04-21T08:41:15.847 に答える