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

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

新規登録して質問してみよう
ただいま回答率
85.37%
プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

414閲覧

csvファイル内の距離行列の全点間の最短距離の算出

nudru

総合スコア4

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/10/17 06:28

イメージ説明

実現したいこと

csvファイル内に距離行列があるが、これをワーシャルフロイド法を用いて全点間の距離を算出し、距離行列を作成したい。
このコードをご教授頂きたいです。

早急にこの距離行列を解かないといけないのですが、実際は2000×2000ぐらいの行列です。

前提

画像のように距離行列がある。
実際は2000×2000の行列である。

発生している問題・エラーメッセージ

エラーメッセージ indentation error

該当のソースコード

Python

1 2import csv 3 4def warshall_floyd(dist): 5 n = len(dist) 6 for k in range(n): 7 for i in range(n): 8 for j in range(n): 9 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) 10 return dist 11 12def read_distance_matrix_from_csv(filename): 13 with open(filename, 'r') as file: 14 reader = csv.reader(file) 15 # ヘッダ行をスキップ 16 next(reader) 17 dist_matrix = [list(map(int, row[1:])) for row in reader] 18 return dist_matrix 19 20# CSVファイルから距離行列を読み取る 21filename = 'path_to_your_csv_file.csv' 22dist = read_distance_matrix_from_csv(filename) 23 24# ワーシャルフロイド法を適用 25result = warshall_floyd(dist) 26 27# 結果を表示 (オプション) 28# for row in result: 29# print(row) 30

試したこと

「# ヘッダ行をスキップ」の最後の「return dist_matrix」でエラーが起こった

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

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

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

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

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

guest

回答1

0

ベストアンサー

「該当のソースコード」を提示されている CSV ファイルで実行すると,

ValueError: invalid literal for int() with base 10: ''

のエラーが生じました。

これは,空文字列('')を整数に変換しようとしたことが原因と考えられ,空文字列を特定の数値文字列に置換しておく必要がありますが,今回の目的に合わせて無限大を模した数値文字列 INF = '100000' に置換することにしました。

記述例を下記に示します。

Python

1import csv 2 3def warshall_floyd(dist): 4 n = len(dist) 5 for k in range(n): 6 for i in range(n): 7 for j in range(n): 8 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) 9 return dist 10 11def read_distance_matrix_from_csv(filename): 12 with open(filename, 'r', newline='') as csvfile: 13 reader = csv.reader(csvfile) 14 return [row[1:] for i, row in enumerate(reader) if i > 0] 15 16file_name = 'sample.csv' 17INF = '100000' 18 19d_csv = read_distance_matrix_from_csv(file_name) 20d_str = [[INF if s == '' else s for s in row] for row in d_csv] 21d_int = [[int(s) for s in row] for row in d_str] 22 23for row in d_int: 24 print(row) 25# [0, 10, 100000, 100000, 100000] 26# [10, 0, 8, 21, 100000] 27# [100000, 8, 0, 100000, 100000] 28# [100000, 21, 100000, 0, 16] 29# [100000, 100000, 100000, 16, 0] 30 31result = warshall_floyd(d_int) 32 33for row in result: 34 print(row) 35# [0, 10, 18, 31, 47] 36# [10, 0, 8, 21, 37] 37# [18, 8, 0, 29, 45] 38# [31, 21, 29, 0, 16] 39# [47, 37, 45, 16, 0]

(追記)
結果を CSV ファイルに保存するコードを追記します。

なお,最初の2行はヘッダとインデックスを追加するためのものです。必要なければコメントアウト等をしてください。

Python

1result = [[i + 1 for i, _ in enumerate(result)]] + result 2result = [[i if i > 0 else ''] + row for i, row in enumerate(result)] 3 4with open('result_' + file_name, 'w', newline='') as csvfile: 5 writer = csv.writer(csvfile) 6 writer.writerows(result)

(追記2)
結果を CSV ファイルへ保存する部分も含めたコード全体を示します。

処理する 2000x2000 の CSV ファイルの「コピー」を作業フォルダに移動し,その名前を data_2000.csv に変更してから実行してください。

Python

1import csv 2 3def warshall_floyd(dist): 4 n = len(dist) 5 for k in range(n): 6 # print(k) 7 for i in range(n): 8 for j in range(n): 9 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) 10 return dist 11 12def read_distance_matrix_from_csv(filename): 13 with open(filename, 'r', newline='') as csvfile: 14 reader = csv.reader(csvfile) 15 return [row[1:] for i, row in enumerate(reader) if i > 0] 16 17file_name = 'data_2000.csv' 18INF = '100000' 19 20d_csv = read_distance_matrix_from_csv(file_name) 21d_str = [[INF if s == '' else s for s in row] for row in d_csv] 22d_int = [[int(s) for s in row] for row in d_str] 23 24result = warshall_floyd(d_int) 25 26with open('result_' + file_name, 'w', newline='') as csvfile: 27 writer = csv.writer(csvfile) 28 writer.writerows(result)

投稿2023/10/17 15:24

編集2023/10/19 14:45
little_street

総合スコア402

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

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

nudru

2023/10/18 01:44

little_street様 ありがとうございます。 送って頂いたコードの、25〜29行目の行列がcsvファイル内の行列を入れると思うのですが、私が算出したい行列は2000×2000ほどなので、どのようにすればよろしいでしょうか。
little_street

2023/10/18 15:49 編集

実際にこのコードを使う場合には,実害はありませんが紛らわしいので25から29行目と35から39行目は削除しておいた方が良いでしょう。 2000x2000 のデータが格納された CSV ファイルの名前が仮に data_2000.csv だとすると以下の設定をして実行すれば良いと思います。 file_name = 'data_2000.csv' ただし,結果も 2000x2000 になるので画面に出力せず CSV ファイルに保存した方が良いでしょう。コードを回答に追記しました。 なお,このプログラムを使う頻度が低ければ許容範囲かもしれませんが,Python のループ処理は速いとは言えません。私の環境(macOS(M1),Python 3.11.6)で 500x500 のデータで試したところ計算時間が約 13 秒かかったので,2000x2000 なら(3重ループなので 4x4x4 =)64 倍の 800 秒以上かかる計算になります。
nudru

2023/10/19 13:48

ありがとうございます。 csvファイルとして読み取れればいいため、23〜29,33〜39は無視しました。 31行目を打ち、改行したときに>>>が出ず、文字が打てなかったためここも無視さしたのですがよろしいでしょうか? また、これで進め、送って頂いた2つ目のコードの1,2行目は無視し、それ以降はそのままコピペすると、以下のようなエラーが出たのですがどのようにすればよろしいでしょうか。 16行目の時にファイルのことでエラーが出なかったので、なぜここでエラーが起きたのかわかりません。 Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 22] Invalid argument: 'csvファイルのパス'
little_street

2023/10/19 14:51

とりあえず,回答にコード全体を追記(追記2)しました。
nudru

2023/10/20 06:10

ありがとうございます。 idleでやったのですが、 コードを書く前の上の部分の Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license()" for more information. で、最初の方の8b6ee5bの8が赤くなり、syntaxerror、invalid decimal literalとなりました。
little_street

2023/10/20 15:24 編集

idle は(ほとんど使ったことがないですが)今回のようなケースでは以下の手順でしょうか。 * data_2000.csv を準備したフォルダで idle を起動 * File > New File でエディタを起動 * (追記2)のコードをコピー(右上[+])し,エディタ画面に貼り付け ※ 6行目のコメント(# )をはずしておくと進行(0 -> 1983)がわかりやすい * File > Save as... で適当な名前を付けて保存 * Run > Run Module で実行すると,IDLE Shell 画面で処理が進行(0 -> 1983)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問