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

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

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

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

Q&A

解決済

1回答

473閲覧

処理を高速化したいです。

kakii

総合スコア6

Python

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

0グッド

1クリップ

投稿2020/02/12 14:55

前提・実現したいこと

pythonに関する質問です。
実行したい内容は下記1~4のコードになります。これを高速化する方法はあるでしょうか。
どなたかご教示お願い致します。
1.irisのpetal_length,petal_widthごとに,sepal_lengthの平均値を算出する。
2.irisのsepal_lengthに対して、1で算出した平均値を除く。
3.算出後にデータフレームを結合する。
4.5回繰り返す

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

実行時間が長い。

該当のソースコード

python

1import pandas as pd 2import numpy as np 3import os 4from dfply import * 5from sklearn.datasets import load_iris 6iris = load_iris() 7df = pd.DataFrame(iris['data'],columns=['sepal_length','sepal_width','petal_length','petal_width']) 8petal_length_all = df['petal_length'].unique() 9petal_width_all = df['petal_width'].unique() 10 11df_tmp_summary=pd.DataFrame() 12 13for i in range(0,5): 14 for petal_length_Number in range(0, len(petal_length_all)): 15 for petal_width_Number in range(0, len(petal_width_all)): 16 df_tmp=df >> filter_by(X.petal_length == petal_length_all[petal_length_Number]) >> filter_by(X.petal_width == petal_width_all[petal_width_Number]) 17 df_tmp['sepal_length']=df_tmp['sepal_length'].apply(lambda x: x - df_tmp['sepal_length'].mean()) 18 df_tmp_summary = pd.concat([df_tmp_summary, df_tmp])

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

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

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

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

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

meg_

2020/02/12 15:34

何か調べたり、試したりしたことがあれば質問に追記してください。
kakii

2020/02/14 17:35

ご返信できず、申し訳ありませんでした。for文をできるだけ使用しないようにする、for文を使用する場合は内包表記を使用するようにする等、1つ1つ習得していきたいと思います。
guest

回答1

0

ベストアンサー

Python

1arr = iris['data'] 2sidx = np.lexsort(arr[:, [2, 3]].T) 3arr_s = arr[sidx] 4idx = np.r_[True, (arr_s[1:, [2, 3]] != arr_s[:-1, [2, 3]]).any(1)].nonzero()[0] 5 6sums = np.add.reduceat(arr_s[:, 0], idx, axis=0) 7count = np.r_[idx[1:] - idx[:-1], arr.shape[0] - idx[-1]] 8means = sums / count 9res_arr = arr_s[:, 0] - np.repeat(means, count) 10 11pd.DataFrame(np.concatenate((arr_s, res_arr[:,None]), 1))

を5回繰り返す、で良いでしょうか?

投稿2020/02/12 23:59

kirara0048

総合スコア1399

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

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

kakii

2020/02/14 05:37 編集

ご回答ありがとうございます。 "np.lexsort(arr[:, [2, 3]].T)"の部分で早速つまづいております。 arr[:, [2, 3]].Tでarrの2列目と3列目を取得、転置する。 np.lexsort(~)にて、1つ目の配列で昇順にソート、さらに2つ目の配列で昇順にソートするという意味であっているでしょうか? そうであれば、下記を実行した際に、print(sidx)は[1 5 4 3 2 0]になる気がするのですが、[5 0 4 3 2 1]と出力されてしまいます。 sidx = np.lexsort(arr[4:10, [2, 3]].T) print(arr[4:10, [2, 3]].T) print(sidx)
kirara0048

2020/02/14 06:23

np.lexsort() および np.argsort() で返却されるのは、「元の配列をソートするためのindex」です。 sidx = np.lexsort(arr[4:10, [2, 3]].T) print(arr[4:10, [2, 3]][sidx]) [[1.5 0.1] [1.4 0.2] [1.4 0.2] [1.5 0.2] [1.4 0.3] [1.7 0.4]] (右側が小さい順・右側が同じ値のときは左側小さい順、でソートされています) [1 5 4 3 2 0]というのは、「ソート後何番目に位置するか」かと思われますが、これは「 sidx.argsort() 」で得ることができます。 print(arr[4:10, [2, 3]][sidx][sidx.argsort()]) [[1.4 0.2] [1.7 0.4] [1.4 0.3] [1.5 0.2] [1.4 0.2] [1.5 0.1]] (元の配列に戻りました)
kakii

2020/02/14 17:33

ようやくすべてが理解できました。 今まで私のPCでは13秒程度かかっていた処理でしたが、ほぼ0秒で処理できるようになりました! numpyを正確に理解し、使いこなすことでここまで処理が速くなることに驚きました。。 また別の質問をさせていただくと思いますが、引き続きどうぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問