質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Python 3.x

    5318questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pythonから日本語CSVが出力出来ない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 146

obakemaru

score 3

お世話になります。

環境はwindows10 python3.6です。
下記のpyファイルを用いてコマンドプロンプト上で

test.py > result.csv
とし、csvを出力しています。

import csv
import os.path

dirname = os.path.dirname(__file__)
path = os.path.join(dirname,"test.csv")

f = open(path, "r", encoding="utf-8")
reader = csv.DictReader(f)
for line in reader:
    print(line["status"],",",line["user_id"])
f.close()

当コードは status も user_id も数字、英語の為問題無いのですが、
user_idやstatusが日本語になった場合に、
UnicodeEncodeError: 'cp932' codec can't encode character '\u5434' in position 0: illegal multibyte sequence
となり、出力する事が出来ません。

どの様にすれば日本語ファイルが出力出来る様になるかご教示頂きたく思います。

 現在はVS codeにコードを書いて、右クリックプロンプトで実行をしています。

 リダイレクトを利用しない方向で考えています。

 辞書型で書き出しを行いたいです。

 csvファイルは40程度の見出しで、数万行です。

 userID_A.csv(userIDとAの情報の組み合わせ)

 userID_B.csv(userIDとBの情報の組み合わせ)

 userID_C.csv(userIDとCの情報の組み合わせ)で出力を行いたいです。

import csv
import os.path

dirname = os.path.dirname(__file__)
path = os.path.join(dirname,"test.csv")
f = opne(path, "w", encoding="utf-8", newline="")

fieldnames = ["status","日本語のデータ"]
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writerrow({"status":std, "日本語のデータ":"日本語"})
f.close()

上記コードだと出来そうですが、行数が数万行ある為、不可能と考えました。
何かリダイレクトせずCSVに一気に書き出せる方法は無いでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • obakemaru

    2018/05/18 17:07 編集

    non

    キャンセル

  • LouiS0616

    2018/05/18 17:15

    ひとつ確認しておきますが、日本語のデータが無い場合はリダイレクトで目的をすべて達成できたのでしょうか?

    キャンセル

  • obakemaru

    2018/05/18 17:47

    はい。日本語の場合以外は目的を達成しています。

    キャンセル

回答 2

+1

リダイレクトを利用しない、簡単な方法を紹介しておきます。

まず、次のように呼び出すと仮定します。

python test.py result.csv

test.pyの頭の方で、標準出力を切り替えるようなコードを書いておきます。

import sys

if len(sys.argv) > 1:
    dst_filename = sys.argv[1]
    sys.stdout = open(dst_filename, 'w', encoding='utf-8')

...

これなら、ほとんど書き換えずに目的の処理が出来るはずです。
ファイルを指定しない場合、標準出力を利用するようにもできました。

ただし

test.pyという名前は、標準モジュールと被るので避けた方が良いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/18 17:14

    ありがとうございます。上記コードをdirname = os.path.dirname(__file__)を上に追加して実行しました。問題無く走ったのですが、ファイルの出力が出来ていない状態です。プロンプト上は表示されている。

    キャンセル

  • 2018/05/18 17:22

    カレントディレクトリは確認されましたか?

    キャンセル

checkベストアンサー

0

コマンドライン引数で受け取るところまではLouiS0616さんと一緒ですが、sys.stdoutを上書きするよりこっちの方法が恐らく良いです。

import csv
import os.path

dirname = os.path.dirname(__file__)
path = os.path.join(dirname,"test.csv")
dst_filename = sys.argv[1]

f_in = open(path, "r", encoding="utf-8")
f_out = open(dst_filename, 'w', encoding='utf-8')
reader = csv.DictReader(f_in)
for line in reader:
    print(line["status"],",",line["user_id"], file=f_out)
f_in.close()
f_out.close()

でも、そもそもこれよりこっちを使うべき。csv.writer.writerowでいけます。

Pythonでcsvファイルにデータを書き込みをする基本中の基本

import csv
import os.path

dirname = os.path.dirname(__file__)
path = os.path.join(dirname,"test.csv")
dst_filename = sys.argv[1]

f_in = open(path, "r", encoding="utf-8")
f_out = open(dst_filename, 'w', encoding='utf-8', newline='')  # can110様のご指摘をうけて改善
reader = csv.DictReader(f_in)
writer = csv.writer(f_out)
for line in reader:
    writer.writerow([line["status"], line["user_id"]])
f_in.close()
f_out.close()

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/18 17:08

    ありがとうございます。
    ただし上記のコードを実行するとIndexError: list index out of rangeとなる様です。

    キャンセル

  • 2018/05/18 18:31 編集

    ・どっちのコードですか?
    ・あと、どこでそのエラーが出ますか?
    ・実行時のコマンドも教えてください
    以上3点について教えてください

    キャンセル

  • 2018/05/18 18:38

    open(dst_filename, 'w', encoding='utf-8')にて「newline=''」を指定しないと、改行がだぶって出力されてしまう(行毎にCRCRLFが出力される)ようです。

    キャンセル

  • 2018/05/18 18:50 編集

    すみません、windows環境で確認していませんでした。csv.writerの方ですね。修正しました。ご指摘ありがとうございます

    キャンセル

  • 2018/05/18 18:52

    はい。Win10環境です。修正対応ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python 3.x

    5318questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。