web-dev-qa-db-ja.com

ヒキガエルエクスポートされたcsvファイルを読み込んだ後、最初の列名に奇妙な文字が追加される

Toadを使用してエクスポートされたR(read.csv("file_name.csv"))のcsvファイルを読み取ると、最初の列名の前に次の文字が表示されます。私.."。また、Excelまたはnotepad ++でcsvファイルを開くと、正しく表示されます(前の文字なしで)。私の回避策は、各読み取り後に列の名前を変更することでしたので、面倒です。この問題の修正に感謝します!

編集:
エクスポートは、クエリの結果セットを右クリックして選択すると、Toadで作成されました
'クイックエクスポート->ファイル-> CSVファイル'

コメントごとの詳細:
head(readLines('test_file.csv'),n=3)
[1] "ID,LOCATION" "12021,1204" "12281,1204"

19
amunategui

これを試して:

d <- read.csv("test_file.csv", fileEncoding="UTF-8-BOM")

これはR 3.0.0以降で機能し、ファイルに存在する場合はBOMを削除します(Microsoftアプリケーションから生成されたファイルに共通:Excel、SQLサーバー)

31
Victor Castro

私はこれが非常に古い質問であることを知っていますが、私が見つけた最も簡単な解決策はNotePad ++を使用することです。 NotePad ++でCSVファイルを開き、[エンコード]をクリックして、[UTF-8でエンコード]を選択してファイルを保存します。 BOMが削除され、元のコードが機能するはずです。

3
ikilltheundead

データサイエンスに使用される多言語コンテンツが増え続けているため、utf-8を想定する安全な方法はもはやありません(私の場合、ExcelがUTF-16を想定しているのは、ほとんどのデータに繁体字中国語(北京語?)が含まれているためです)。

Microsoft Docs によると、Windowsでは次のBOMが使用されています。

|----------------------|-------------|-----------------------|
| Encoding             | Bom         | Python encoding kwarg |
|----------------------|-------------|-----------------------|
| UTF-8                | EF BB BF    | 'utf-8'               |
| UTF-16 big-endian    | FE FF       | 'utf-16-be'           |
| UTF-16 little-endian | FF FE       | 'utf-16-le'           |
| UTF-32 big-endian    | 00 00 FE FF | 'utf-32-be'           |
| UTF-32 little-endian | FF FE 00 00 | 'utf-32-le'           |
|----------------------|-------------|-----------------------|

ファイルの先頭でバイトオーダーマークを使用してエンコーディングを検出するのに適しているように見える次のアプローチを思いつきました。

def guess_encoding_from_bom(filename, default='utf-8'):
    msboms = dict((bom['sig'], bom) for bom in (
        {'name': 'UTF-8', 'sig': b'\xEF\xBB\xBF', 'encoding': 'utf-8'},
        {'name': 'UTF-16 big-endian', 'sig': b'\xFE\xFF', 'encoding':
            'utf-16-be'},
        {'name': 'UTF-16 little-endian', 'sig': b'\xFF\xFE', 'encoding':
            'utf-16-le'},
        {'name': 'UTF-32 big-endian', 'sig': b'\x00\x00\xFE\xFF', 'encoding':
            'utf-32-be'},
        {'name': 'UTF-32 little-endian', 'sig': b'\xFF\xFE\x00\x00',
            'encoding': 'utf-32-le'}))

    with open(filename, 'rb') as f:
        sig = f.read(4)
        for sl in range(3, 0, -1):
            if sig[0:sl] in msboms:
                return msboms[sig[0:sl]]['encoding']
        return default


# Example using python csv module
def excelcsvreader(path, delimiter=',',
                doublequote=False, quotechar='"', dialect='Excel',
                escapechar='\\', fileEncoding='UTF-8'):
    filepath = os.path.expanduser(path)
    fileEncoding = guess_encoding_from_bom(filepath, default=fileEncoding)
    if os.path.exists(filepath):
        # ok let's open it and parse the data
        with open(filepath, 'r', encoding=fileEncoding) as csvfile:
            csvreader = csv.DictReader(csvfile, delimiter=delimiter,
                doublequote=doublequote, quotechar=quotechar, dialect=dialect,
                escapechar='\\')
            for (rnum, row) in enumerate(csvreader):
                yield (rnum, row)

これには2回読み取るためにファイルを開く必要があることを認識しています(1回はバイナリ、もう1回はエンコードされたテキストとして)。この特定のケースでは、APIを使用しないと簡単に実行できません。

とにかく、これは単にutf-8を仮定するよりも少し堅牢で、明らかに自動エンコーディング検出が機能していないと思います...

2
SkyLeach

これをさらに調査した後、BOM(バイトオーダーマーク)が追加された文字と関係があります。どうやらクイックエクスポートを使用できないようですが、データエクスポートWizard代わりにファイルエンコーディングを設定できるため、Unicode utf-8ではなく西ヨーロッパ(Windows)に設定することでうまくいきました。

参照 ファイルの先頭から¿"¿を削除するにはどうすればよいですか?

0
amunategui