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

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

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

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

Q&A

解決済

2回答

2195閲覧

pythonのプログラムの高速化

km1300

総合スコア12

Python

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

0グッド

0クリップ

投稿2017/05/12 04:02

pythonのプログラムなのですが、処理にかかる時間が長く困っています。改善策があれば教えてください。

python

1m2 = np.empty((0,80)) 2for x in m: 3 tmp = np.empty(0) 4 tmp2 = np.empty(0) 5 for y in x: 6 tmp2 = np.append(tmp2,y) 7 count += 1 8 if count == 100: 9 tmp=np.append(tmp,np.max(tmp2)) 10 tmp2 = np.empty(0) 11 count = 0 12 m2 = np.concatenate((m2,tmp.reshape(1, 80)),axis=0)

ちなみに、mは80x8000の配列です。
よろしくお願いします。

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

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

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

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

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

guest

回答2

0

単なるアイデアですが、

ご質問のコードは8000要素の軸に対して100要素のグループごとに最大値を取り出しそれを80要素の配列の形の結果にし0軸目で連結して80x80の結果を得るというものだと思います。

最大値を求めるためだけに一時的な配列tmp2を生成している部分が性能を劣化させている要因に思えます。numpyのmaxは多次元の配列の特定の軸にそって最大値を求めるという能力を持っていますので、

(1) 80x8000->80x80x100にreshape
(2) 第2軸に沿ってmaxを求める

この2ステップで80x80で結果が求まり、元のコードより速いのではないかと思います。

追記:
numpyの実装はpythonの制御文で配列を生成したり1行ずつ連結したりを自前で記述するよりははるかに高速で動作するであろうということを想定しています。実際のpython処理系やnumpyの実装を詳しく知っているわけではないので単なるあて推量です。なお、reshapeは配列の形状を変更しますが、元の配列データは共用されるため二倍のメモリーを消費するわけではないと思います。つまりどんなに大きな配列でも配列の要素を一つ一つコピーしているわけではないと思うので、ほぼ一瞬でreshapeができると思います。(違ってたらすみません)

簡単な例を挙げます。

python

1import numpy as np 2 3m = np.array([[1,2, 3, 4], [5, 6, 7, 8]]) 4m2 = m.reshape(2, 2, 2) 5print('-- after reshape --') 6print(m2) 7m3 = np.max(m2, axis=2) 8print('-- after max --') 9print(m3) 10 11#--結果-- 12-- after reshape -- 13[[[1 2] 14 [3 4]] 15 16 [[5 6] 17 [7 8]]] 18-- after max -- 19[[2 4] 20 [6 8]]

投稿2017/05/12 04:32

編集2017/05/12 04:42
KSwordOfHaste

総合スコア18394

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

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

0

ベストアンサー

こんな感じでどうでしょうか?

Python

1import numpy as np 2 3l = [] 4for i in range(0,m.shape[1],100): 5 l.append(np.max(m[:, i:i+100], axis=1).reshape(80,1)) 6ret = np.hstack(l) 7print(ret)

簡単に手順を説明すると

  1. [8000x80]のサイズの行列を [100x80] のサイズに縦分割して 80回のループを回す。
  2. 各行列毎に横軸方向(axis=1)の最大値を求める。(サイズ[80]のベクトルデータが得られます。)
  3. 80個のベクトルデータを縦行列に変換して再合成

となります。

この方法だと、ループ回数・コピー回数共に激減するので、かなり高速になるのではないでしょうか。

補足として、 m のサイズ[8000x80] が固定ということであれば、

Python

1for i in range(0,m.shape[1],100): 2 l.append(np.max(m[:, i:i+100], axis=1).reshape(80,1))

の部分は

Python

1for d in np.hsplit(m, 80): 2 l.append((np.max(d, axis=1)).reshape(80,1))

と更にシンプルに書けます。(速度は不明)

最後にこれをワンライナーで書くとこんな感じ。(完全に蛇足)

Python

1ret = np.hstack([np.max(d, axis=1).reshape(80,1) for d in np.hsplit(m, 80)])

投稿2017/05/12 07:16

magichan

総合スコア15898

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問