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

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

新規登録して質問してみよう
ただいま回答率
85.48%
バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

Python 3.x

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

Q&A

解決済

2回答

4136閲覧

バイナリファイルの読み込みを高速にしたい

Lily_1007

総合スコア35

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

Python 3.x

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

0グッド

0クリップ

投稿2022/03/24 02:24

編集2022/03/24 06:10

前提

N = 31848305のセルにそれぞれcxyz, velo, den, T, ZSNII, ZSNIaという情報が入っているバイナリファイルを読み込みたいと考えています。

実現したいこと

下のソースコートで現在読み込んでいますが、読み込む数が多すぎて、非常に遅いです。
読み込んだあとに、ndarrayに情報を入れ込んでいるという感じです。高速化したいのですが、他にどのような方法があるのでしょうか。また、Cの方が早いのでしょうか。

該当のソースコード

python

1#initialize: 2cell_size = np.array(1 * [0.]) 3Level_array = np.array(1 * [0.]) 4x = np.array(1 * [0.]) 5y = np.array(1 * [0.]) 6z = np.array(1 * [0.]) 7Vx = np.array(1 * [0.]) 8Vy = np.array(1 * [0.]) 9Vz = np.array(1 * [0.]) 10Den_array = np.array(1 * [0.]) 11Tem_array = np.array(1 * [0.]) 12ZSNII_array = np.array(1 * [0.]) 13ZSNIa_array = np.array(1 * [0.]) 14for i in range(0,N): 15 if(i % 1000000 == 0): 16 print("%9d/%9d" % (i, N)) 17 f.seek(i*13*4+4) 18 bytes = f.read(16) 19 cxyz = struct.unpack('>ffff', bytes) 20# 21 f.seek(i*13*4+20) 22 bytes = f.read(12) 23 velo= struct.unpack('>fff', bytes) 24# 25 f.seek(i*13*4+32) 26 bytes = f.read(4) 27 Den = struct.unpack('>f', bytes) 28# 29 f.seek(i*13*4+36) 30 bytes = f.read(4) 31 T = struct.unpack('>f', bytes) 32# 33 f.seek(i*13*4+40) 34 bytes = f.read(4) 35 ZSNII = struct.unpack('>f', bytes) 36# 37 f.seek(i*13*4+44) 38 bytes = f.read(4) 39 ZSNIa = struct.unpack('>f', bytes) 40   if j==0: 41 cell_max_reso=cxyz[0] 42 cell_size[0]= cxyz[0] 43 Level_array[0]= 1. 44 x[0] = cxyz[1] 45 y[0] = cxyz[2] 46 z[0] = cxyz[3] 47 Den_array[0]= Den[0] 48 Tem_array[0]= T[0] 49 ZSNII_array[0]=ZSNII[0] 50 ZSNIa_array[0]=ZSNIa[0] 51 else: 52 cell_size = np.append(cell_size, cxyz[0]) 53 Level_array = np.append(Level_array, np.log2(cxyz[0]/cell_max_reso) ) 54 x = np.append(x, cxyz[1] ) 55 y = np.append(y, cxyz[2] ) 56 z = np.append(z, cxyz[3] ) 57 Den_array = np.append(Den_array, Den[0]) 58 Tem_array = np.append(Tem_array, T[0]) 59 ZSNII_array = np.append(ZSNII_array, ZSNII[0] ) 60 ZSNIa_array = np.append(ZSNIa_array, ZSNIa[0] )

補足情報(FW/ツールのバージョンなど)

macbook pro, Monterey, python3.8
ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

そりゃそんな細切れにファイルを読み込んで分解、代入を繰り返してたら遅くなります
一気にメモリ上にファイルを読み込み、あとはメモリ上の操作としていきましょう


うごかしてませんが(動かせませんが)、こんなもんでどうでしょう

python

1bytes=f.read( 3184830個分のサイズ) 2for 3184830回ループ: 3 ofs=i*1個分の変数サイズ 4 cxyz = struct.unpack_from('>ffff', bytes,ofs+0) 5 velo= struct.unpack_from('>fff', bytes,ofs+16) 6 Den = struct.unpack_from('>f', bytes,ofs+28) 7 なんやかや 8

投稿2022/03/24 02:51

編集2022/03/24 05:32
y_waiwai

総合スコア87774

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

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

Lily_1007

2022/03/24 03:06

このような操作が始めてでよく分からないのですが、 一気にメモリ上にファイルを読み込むというのは どういうコマンドに対応しているのでしょうか
y_waiwai

2022/03/24 04:14 編集

例えばその変数群の1万個分のデータをファイルから一気に読み込みます bytes = f.read(変数サイズ*10000) あとはbytesから1万個分展開していけばいいです
Lily_1007

2022/03/24 04:30

すみません、bytesから展開とはどういうことでしょうか?
y_waiwai

2022/03/24 05:09

そのバイト配列から、変数を読み込めばいいのです
Lily_1007

2022/03/24 05:16

変数が複数あり、それが3000万個あるのです。 結局それだと N_read = 3184830 bytes = f.read(13*4*N_read) for i in range(100000,150000): if(i % 1000000 == 0): print("%9d/%9d" % (i, N)) f.seek(i*13*4+4) bytes = f.read(16) cxyz = struct.unpack('>ffff', bytes) # f.seek(i*13*4+20) bytes = f.read(12) velo= struct.unpack('>fff', bytes) # f.seek(i*13*4+32) bytes = f.read(4) Den = struct.unpack('>f', bytes) # f.seek(i*13*4+36) bytes = f.read(4) T = struct.unpack('>f', bytes) # f.seek(i*13*4+40) bytes = f.read(4) ZSNII = struct.unpack('>f', bytes) # f.seek(i*13*4+44) bytes = f.read(4) ZSNIa = struct.unpack('>f', bytes) となって質問で投げたようなコードになると思っているのですが
Lily_1007

2022/03/24 05:16

具体的にはどういう風に変数を読み込めばよろしいのでしょうか
Lily_1007

2022/03/24 05:19

読み込むとはどういうことでしょうか? 具体的なコマンドを教えていただけると幸いです
Lily_1007

2022/03/24 06:02

コードに関して、誠にありがとうございます。 ofs=i*1個分の変数サイズ って何でしょうか? 1個分の変数サイズとは4バイトということでしょうか?
guest

0

N_read = 10
f = open(filename,mode='rb')
data_bytes =f.read(134N_read)
#print(data_bytes)
#print(struct.calcsize(bytes))
for i in range(N_read):
ofs =i134
cxyz = struct.unpack_from('>ffff', data_bytes,ofs+4)
velo = struct.unpack_from('>fff', data_bytes,ofs+20)
Den = struct.unpack_from('>f', data_bytes,ofs+32)
T = struct.unpack_from('>f', data_bytes,ofs+36)
ZSNII= struct.unpack_from('>f', data_bytes,ofs+40)
ZSNIa= struct.unpack_from('>f', data_bytes,ofs+44)
print(Den, T, ZSNII, ZSNIa)

で解決しました。本当にありがとうございます!

投稿2022/03/24 06:11

Lily_1007

総合スコア35

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問