🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

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

Q&A

解決済

2回答

449閲覧

PythonでCSVを使って新規ファイルとして出力をしたい

penverray

総合スコア0

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

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

0グッド

1クリップ

投稿2020/12/13 07:39

編集2020/12/13 08:55

前提・実現したいこと

python3で、修正元のデータに修正データを適応させ修正後のデータの形で出力をしたいです。
pythonとCSVファイルのみで操作をしたいです。

###コード
修正元のデータ

csv

1No,出勤時刻,退勤時刻,修正理由 21,2020-12-09 14:41,2020-12-09 14:41, 32,2020-12-09 14:56,2020-12-09 14:56, 43,2020-12-09 14:58,2020-12-09 14:58, 54,2020-12-09 15:01,2020-12-09 15:01, 65,2020-12-09 15:11,2020-12-09 15:11, 76,2020-12-09 15:13,2020-12-09 15:13, 87,2020-12-09 15:15,2020-12-09 15:15, 98,2020-12-09 15:18,2020-12-09 15:18,

修正データ

csv

1No,出勤時刻,退勤時刻,修正理由 21,2020-12-07 9:00,,打刻忘れ 31,,2020-12-07 17:00,打刻ミス 42,2020-12-08 9:00,,打刻忘れ 53,,2020-12-08 17:00,打刻ミス 65,2020-12-10 8:30,,打刻忘れ 77,,2020-12-15 17:00,打刻ミス 86,,2020-12-07 19:00,打刻忘れ 95,2020-12-10 8:00,,打刻ミス

修正後のデータ

csv

1No,出勤時刻,退勤時刻,修正理由 21,2020-12-07 9:00,2020-12-07 17:00,打刻ミス 32,2020-12-08 9:00,2020-12-09 14:56,打刻忘れ 43,2020-12-09 14:58,2020-12-09 14:58,打刻ミス 54,2020-12-09 15:01,2020-12-08 17:00, 65,2020-12-10 8:00,2020-12-09 15:11,打刻ミス 76,2020-12-09 15:13,2020-12-07 19:00,打刻忘れ 87,2020-12-09 15:15,2020-12-15 17:00,打刻ミス 98,2020-12-09 15:18,2020-12-09 15:18,

###現段階で試していること・調査中
python側(修正データは読み込んでいません)
nan部分をnanで上書きしたくない(修正データがnanとき、修正元の退勤時間のデータをそのまま使いたい)
Noが1の部分を指定して上書きするコード(間違っている可能性あり)

python

1import csv 2 3 4def read_csv(filename): 5 f = open(filename, "r") 6 csv_data = csv.reader(f) 7 list1 = [e for e in csv_data] 8 f.close() 9 return list1 10 11 12def update_list2d(list1, data): 13 for i in range(len(list1)): 14 if list1[i][0] == data[0]: list1[i] = data 15 return list1 16 17 18def write_csv(filename, list1): 19 with open(filename, 'w', newline='') as f: 20 writer = csv.writer(f) 21 writer.writerows(list1) 22 23 f.close() 24 25 26def main(): 27 #csvファイルのパス 28 csv_path = "data1.csv" 29 #csvファイルのロード 30 csv_data = read_csv(csv_path) 31 32 data = ["1", "2020-12-09 14:42", nan, ""] 33 csv_data2 = update_list2d(csv_data, data) 34 write_csv(csv_path, csv_data2) 35 36 37if __name__ == '__main__': 38 main()

条件

修正データの空白の部分は修正元のデータをそのまま使う
Noを参照して上の行から下の行までを順次適応させたい

補足情報

・python3.6
・修正元:data1.csv
・修正データ:fix.csv
・修正後:data1_after.csv

修正元のNoは修正データの参照元と仮定しています
修正データのNoは修正元の参照先と仮定しています
また、過去に似たような質問があった場合は、リンクを載せていただけると幸いです。

###追記
手段は問いません。
おかしい部分があった場合は指摘をいただけると幸いです。
素人なのでどなたかご教授くだされば幸いです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

python

1 2import pandas as pd 3import numpy as np 4 5header = ("No", "出勤時刻", "退勤時刻", "修正理由") 6data1 = pd.read_csv("data.csv", names=header).fillna(-1111) # 打刻データを読み込み。+nanを-1111に置換 7data2 = pd.read_csv("fix.csv", names=header).fillna(-1111) # 修正データを読み込み。+nanを-1111に置換 8npArray1 = data1.values 9npArray2 = data2.values 10ri = 1 # 行 npArray1 11rj = 1 # 行 npArray2 12max_count = npArray1.shape[0] # 打刻データの行数を取得 13 14while ri < max_count: 15 for j in npArray2: 16 if npArray1[ri, 0] == npArray2[rj, 0]: # npArray1とnpArray2は等しいか? 17 if npArray2[rj, 1] != -1111: # npArray2[*,?]の出勤時刻はnanではないか? 18 npArray1[ri, 1] = npArray2[rj, 1] # 出勤時刻に書き込み 19 if npArray2[rj, 2] != -1111: # npArray2[*,?]の退勤時刻はnanではないか? 20 npArray1[ri, 2] = npArray2[rj, 2] # 退勤時刻に書き込み 21 npArray1[ri, 3] = npArray2[rj, 3] # 修正理由に書き込み 22 rj += 1 23 else: # nanの場合 24 npArray1[ri, 3] = npArray2[rj, 3] # 修正理由に書き込み 25 rj += 1 26 else: # nanの場合 27 if npArray2[rj, 2] != -1111: # npArray2[*,?]の退勤時刻はnanではないか? 28 npArray1[ri, 2] = npArray2[rj, 2] # 退勤時刻に書き込み 29 npArray1[ri, 3] = npArray2[rj, 3] # 修正理由に書き込み 30 rj += 1 31 else: # nanの場合 ※存在しません 32 pass 33 else: 34 pass 35 ri += 1 36else: 37 pass 38 39df = pd.DataFrame(npArray1) 40df.to_csv('after.csv', index=False, header=False) 41 42fn = "after.csv" 43with open(fn, "r") as f: 44 s = f.read() 45s = s.replace("-1111", '') 46with open(fn, "w") as f: 47 f.write(s)

###解決方法・手順
1.pandasでファイルを読み込み nanを-1111(何でも良いがデータに影響しない数)に置換。
2.それぞれをnumpyで変換
3.ループ処理
4.numpyからpandasに変換
5.書き込み(インデックスとヘッダーを書き込まないようにする)
6.-1111の部分を置換
7.置換したものを書き込み
###終わり
たぶんもっといい解決方法があるとは思うが私は、この方法で出来た。

投稿2020/12/19 10:46

penverray

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ファイルの書き換えをする、ということはできません。
あくまで、
ファイルの作り直しを行う、しかできませんよ

投稿2020/12/13 07:46

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

penverray

2020/12/13 09:36

早速回答ありがとうございます。知識不足で申し訳ありません。 ファイルの作り直しをする場合のやり方がわからず戸惑っています。 現在、指定した行の上書きしかやり方が分かっていません。 どのような方法を使いファイルを作り直せば良いのでしょうか?
y_waiwai

2020/12/13 10:10

やり方としては2通りです すべてのデータを読み込み、読み込んだデータを修正し、既存のデータを削除、新規作成してデータ書き込み。 もう一つは、別のファイル名でファイル作成、元データ読み込みながら、データ修正して書き込み、すべて終わったあとで、元ファイルを削除(あるいはバックアップとしてリネーム)、そして、作成したファイルを、元ファイルにリネーム ですね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問