質問するログイン新規登録

Q&A

解決済

1回答

233閲覧

ファイルの読み込みがよく分かりません

yyicp

総合スコア91

Python

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

1グッド

0クリップ

投稿2025/11/27 06:41

1

0

実現したいこと

sample1.txtは次のようなファイルです。

1 2 3 7 8 9

sample2.txtは次のようなファイルです。

4 5 6

3行の各塊は順に
i方向インデックス
j方向インデックス
k方向インデックス
を意味しています。

今、sample1.txt、sample2.txtの各塊の中で最大値を取り出したいと思い、「該当のソースコード」を書きました。39~44行目の出力がおかしいです。どなたか正しいコードに直してください。

該当のソースコード

python

1import pandas as pd 2from glob import glob 3 4data_files = glob('*.txt') 5 6for f in data_files: 7 # 3行ごとに読み込み(空行はスキップされる) 8 blks = [blk.to_numpy() for blk in pd.read_csv(f, header=None, chunksize=3)] 9 10 imin = 1000 11 jmin = 1000 12 kmin = 1000 13 imax = 0 14 jmax = 0 15 kmax = 0 16 17 for l, blk in enumerate(blks): 18 # 2番目以降のブロックでは空行を入れる 19 if l > 0: print('') 20 21 i = blk[0] 22 j = blk[1] 23 k = blk[2] 24 25 if i<imin: 26 imin=i 27 if j<jmin: 28 jmin=j 29 if k<kmin: 30 kmin=k 31 32 if i>imax: 33 imax=i 34 if j>jmax: 35 jmax=j 36 if k>kmax: 37 kmax=k 38 39print(imin)#4、本来は1と出力したい 40print(jmin)#5、本来は2と出力したい 41print(kmin)#6、本来は3と出力したい 42print(imax)#4、本来は7と出力したい 43print(jmax)#5、本来は8と出力したい 44print(kmax)#6、本来は9と出力したい

試したこと

31行目に

print('imin='+str(imin))

を追加して実行すると、この部分に相当する出力は以下のようになりましたが、なぜこうなるのかがよく分かりませんでした。

imin=[1] imin=[1] imin=[4]
melian👍を押しています

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

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

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

melian

2025/11/27 07:49 編集

手元の環境(Python 3.13.7/Pandas 2.3.3)で実行すると、結果は本来の値([1] [2] [3] [7] [8] [9])になります。読み込んでいるデータファイルが別のものになっていたりはしないでしょうか? それから、blk が Pandas の dataframe なので、blk.to_numpy() は shape が (3, 1) の2次元配列になります。blk[0].to_numpy() とすれば、Pandas の series を numpy 配列に変換するので1次元配列になります。 blks = [blk.to_numpy() for blk in pd.read_csv(f, header=None, chunksize=3)] => blks = [blk[0].to_numpy() for blk in pd.read_csv(f, header=None, chunksize=3)] 上記の変更を行って実行すると、結果は以下の様になります。 1 2 3 7 8 9
yyicp

2025/11/27 07:45

>melian様 コメントありがとうございます。 データファイルが正しいものを読み込んでいることを確認しました。 私の環境は、Python 3.13.6、Pandas 2.3.1でした。 各々バージョンを上げてやってみます。
TakaiY

2025/11/27 07:53

横からすみません。 > データファイルが正しあすかいものを読み込んでいることを確認しました。 どのように確認していますか? また、globに指定しているファイル名をその想定しえちるファイルのあるフルパスにするとどうなりますか?
yyicp

2025/11/27 08:04

>melian様 追加のコメントありがとうございます。 pandasを2.3.3に上げましたが、うまくいきませんでした。 (pythonのバージョンはまだ3.13.6です) blks = [blk[0].to_numpy() for blk in pd.read_csv(f, header=None, chunksize=3)] としてみましたが、うまくいきませんでした。
yyicp

2025/11/27 08:13

>TakaiY様 コメントありがとうございます。 プログラムと同じフォルダにあることを確認しました。 「該当のソースコード」の24行目に print(i) print(j) print(k) を加えて実行すると、その部分の出力が、 1 2 3 7 8 9 4 5 6 になりました。
melian

2025/11/27 08:16

以下のコードを実行してもらえますか? 処理内容は同じです。手元の環境では「本来の結果」と同じ結果になります。 https://www.mycompiler.io/view/9dGcGCvTLGL
yyicp

2025/11/27 08:40

>melian様 「該当のコード」で正しい結果が表示されました。 ありがとうございました。 回答欄への記入をお願いします。 ところで、私の環境ではうまくいかなかった理由はよく分からないということでしょうか。
melian

2025/11/27 08:52

はい、処理内容は同じでデータファイル(*.txt)の中身も同じとなると何が原因なのか、、、
yyicp

2025/11/27 09:02

>melian様 pythonを3.14.0に上げましたが、結果は変わりませんでした。
yyicp

2025/11/28 01:33 編集

>melian様 あと違うのは、OSぐらいでしょうか。 私はWindows11、melian様はUNIXでしょうか。 まあ、これ以上深追いしないことにします。
melian

2025/11/28 01:24

こちらは Ubuntu Linux 25.10 ですが、最小値と最大値が 4 5 6 になっていることを考えると、sample2.txt だけが読み込まれている状況の様に見えますね。。。
yyicp

2025/11/28 01:33

往生際が悪くて申し訳ありません。 プログラムがあるフォルダからsample2.txtを消すと、つまりsample1.txtだけに対してプログラムを適用するとプログラムは正しく動作しました。2個目のファイルを読み込むときに1個目のファイルの結果が保存されていないような気がします。
yyicp

2025/11/28 01:42 編集

26行目の次に print(str(i)+'\t'+str(imin)) を足すと、その部分の出力が以下のようになります。 1 1 4 4 こちらとしては以下のようになるはずだと思っていますが・・・ 1 1 4 1
yyicp

2025/11/28 02:04

10~15行目を4行目の後に移動したらうまくいきました。 melian様の環境では「該当のソースコード」がうまくいく理由にはなっていませんが。
melian

2025/11/28 02:10

> 10~15行目を4行目の後に移動したらうまくいきました。 分かりました。imin, jmin, kmin, imax, jmax, kmax がデータファイルを読み込む度にリセットされてしまうことが原因だったのですね。こちらの環境で上手くいっていたのは、glob("*.txt") の結果が ["sample2.txt", "sample1.txt"] になっていて、sample2.txt が先に読み込まれていたためでした。sorted(glob("*.txt")) に変更して "sample1.txt" を先に読み込むと 4 5 6 4 5 6 になります。
yyicp

2025/11/28 02:15

長い間お付き合いいただいて、どうもありがとうございました。
guest

回答1

0

ベストアンサー

データファイルから3行ごとにデータフレームとして読み込んでから pandas.concat(axis=1) で列方向に連結します。最小値と最大値はそれぞれ pandas.DataFrame.min()pandas.DataFrame.max() で求めることができます。

python

1import pandas as pd 2from glob import glob 3 4data_files = glob('*.txt') 5# print(data_files) 6df = pd.concat([blk.reset_index(drop=True) for f in data_files 7 for blk in pd.read_csv(f, header=None, chunksize=3)], 8 axis=1) 9# print(df) 10 11imin, jmin, kmin = df.min(axis=1) 12imax, jmax, kmax = df.max(axis=1) 13print(imin) 14print(jmin) 15print(kmin) 16print(imax) 17print(jmax) 18print(kmax)

投稿2025/11/27 08:47

melian

総合スコア21564

yyicp

2025/11/27 08:52

できました。 どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問