実現したいこと
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]
手元の環境(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
>melian様
コメントありがとうございます。
データファイルが正しいものを読み込んでいることを確認しました。
私の環境は、Python 3.13.6、Pandas 2.3.1でした。
各々バージョンを上げてやってみます。
横からすみません。
> データファイルが正しあすかいものを読み込んでいることを確認しました。
どのように確認していますか?
また、globに指定しているファイル名をその想定しえちるファイルのあるフルパスにするとどうなりますか?
>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)]
としてみましたが、うまくいきませんでした。
>TakaiY様
コメントありがとうございます。
プログラムと同じフォルダにあることを確認しました。
「該当のソースコード」の24行目に
print(i)
print(j)
print(k)
を加えて実行すると、その部分の出力が、
1
2
3
7
8
9
4
5
6
になりました。
以下のコードを実行してもらえますか? 処理内容は同じです。手元の環境では「本来の結果」と同じ結果になります。
https://www.mycompiler.io/view/9dGcGCvTLGL
>melian様
「該当のコード」で正しい結果が表示されました。
ありがとうございました。
回答欄への記入をお願いします。
ところで、私の環境ではうまくいかなかった理由はよく分からないということでしょうか。
はい、処理内容は同じでデータファイル(*.txt)の中身も同じとなると何が原因なのか、、、
>melian様
pythonを3.14.0に上げましたが、結果は変わりませんでした。
>melian様
あと違うのは、OSぐらいでしょうか。
私はWindows11、melian様はUNIXでしょうか。
まあ、これ以上深追いしないことにします。
こちらは Ubuntu Linux 25.10 ですが、最小値と最大値が 4 5 6 になっていることを考えると、sample2.txt だけが読み込まれている状況の様に見えますね。。。
往生際が悪くて申し訳ありません。
プログラムがあるフォルダからsample2.txtを消すと、つまりsample1.txtだけに対してプログラムを適用するとプログラムは正しく動作しました。2個目のファイルを読み込むときに1個目のファイルの結果が保存されていないような気がします。
26行目の次に
print(str(i)+'\t'+str(imin))
を足すと、その部分の出力が以下のようになります。
1 1
4 4
こちらとしては以下のようになるはずだと思っていますが・・・
1 1
4 1
10~15行目を4行目の後に移動したらうまくいきました。
melian様の環境では「該当のソースコード」がうまくいく理由にはなっていませんが。
> 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 になります。
長い間お付き合いいただいて、どうもありがとうございました。
回答1件
あなたの回答
tips
プレビュー