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

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

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

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

Q&A

解決済

4回答

1977閲覧

処理速度を上げるためのプログラムの書き方

wpspring0300

総合スコア11

Python

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

1グッド

2クリップ

投稿2018/09/21 04:11

編集2018/09/21 04:12

pythonで距離関数DTWを使用したk-means法を実装したのですが,実行するのにすごく時間がかかってしまうため,実用的ではないのですが、どこを変えれば処理内容は変わらず処理速度を上げることができるのかアドバイスいただきたいと思っております。

python

1import numpy as np 2import pandas as pd 3from scipy.spatial.distance import euclidean 4from fastdtw import fastdtw 5import glob 6import random 7 8d = glob.glob('*_m.csv') 9df = pd.DataFrame() 10df7 = pd.DataFrame() 11df8 = pd.DataFrame() 12df9 = pd.DataFrame() 13df11 = pd.DataFrame() 14v = 3 15k = 546 16l = k*v 17r = np.random.randint(0,v,k) 18print(r) 19for n in range(v): 20 n += 1 21 for x in range(k): 22 x += 1 23 a = d[x-1] 24 df1 = pd.read_csv(f'{a}',index_col=0) 25 df1 = df1.groupby(df1.index // 60).mean() 26 for i in range(24): 27 i += 1 28 df7.loc[i-1,x] = df1.iloc[i-1,0] + df1.iloc[i-1,1] 29 df11.loc[i-1,0] = i-1 30 df11.loc[i-1,1] = df1.iloc[i-1,0] + df1.iloc[i-1,1] 31 if r[x-1] == n-1: 32 df8.loc[i-1,x-1] = df7.iloc[i-1,x-1] 33 df9.loc[i-1,0] = i-1 34 df9['1'] = df8.mean(axis=1) 35 distance, path = fastdtw(df11,df9,dist=euclidean) 36 df.loc[n-1,x-1] = distance 37 d1 = [] 38 d1 = df.idxmin(axis=0) 39 for s in range(10): 40 for i in range(24): 41 i += 1 42 df7.loc[i-1,x] = df1.iloc[i-1,0] + df1.iloc[i-1,1] 43 df11.loc[i-1,0] = i-1 44 df11.loc[i-1,1] = df1.iloc[i-1,0] + df1.iloc[i-1,1] 45 if d1[x-1] == n-1: 46 df8.loc[i-1,x-1] = df7.iloc[i-1,x-1] 47 df9.loc[i-1,0] = i-1 48 df9['1'] = df8.mean(axis=1) 49 distance, path = fastdtw(df11,df9,dist=euclidean) 50 df.loc[n-1,x-1] = distance 51 d1 = [] 52 d1 = df.idxmin(axis=0) 53for n in range (v): 54 df12 = pd. DataFrame() 55 n += 1 56 for x in range(k): 57 x += 1 58 if d1[x-1] == n-1: 59 for i in range(24): 60 i += 1 61 df12.loc[i-1,x-1] = df7.iloc[i-1,x-1] 62 df12.to_csv(f'dtw20070701_{n-1}_{v}.csv') 63

乱数を使っているためたまにエラーは出ますが,基本的には正常に動作します。
ちなみに使用しているデータは,546軒分の1分値のデータです。

rikkunblog👍を押しています

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

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

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

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

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

guest

回答4

0

for をがっつり使うアルゴリズムを書きたいなら、C++ で作成して、Python から呼び出したほうがいいです。
ただ規則性がある計算は大抵 for を回さなくても numpy の indexing を使えばすむので、高速に計算できます。

numpy で k平均法の実装サンプル

fastdtw は知らないのですが、k平均法の距離関数を fastdtw に変えるだけではダメなのでしょうか?

サンプルの作成

python

1import numpy as np 2import matplotlib.pyplot as plt 3from sklearn.datasets import make_blobs 4 5# データを作成する。 6X, Y = make_blobs(centers=3, n_samples=500) 7print(X.shape) # (500, 2) 8print(y.shape) # (500,) 9 10# サンプル結果描画 11################################################## 12fig, axes = plt.subplots(figsize=(6, 6)) 13axes.scatter(X[:,0], X[:,1], alpha=0.5, s=10) 14axes.set_xlabel('$x_1$') 15axes.set_ylabel('$x_2$') 16 17num_cluster = 3 18maxiter = 50

イメージ説明

k平均法の numpy による実装例

python

1# ランダムにクラスタの中心を選択する。 2centroids = X[np.random.randint(X.shape[0], size=num_cluster)] 3 4# 各データとクラスタの中心との距離を格納する変数 5distances = np.zeros([X.shape[0], num_cluster], dtype=np.float64) 6 7for i in range(maxiter): 8 # すべての点と各クラスタの中心を計算する。 9 for i, c in enumerate(centroids): 10 distances[:, i] = np.linalg.norm(X - c, axis=1) 11 12 # 最も近いクラスタの中心のクラスに割り当てる。 13 classes = np.argmin(distances, axis=1) 14 15 # クラスタの中心を更新する。 16 for c in range(k): 17 centroids[c] = np.mean(X[classes == c], axis=0)

クラスタリング結果

python

1# クラスタリング結果描画 2################################################## 3cluster_colors = ['skyblue', 'coral', 'lightgreen'] 4colors = [cluster_colors[c] for c in classes] 5 6fig, axes = plt.subplots(figsize=(6, 6)) 7# 各クラスタを描画する。 8axes.scatter(X[:, 0], X[:, 1], color=colors, alpha=0.5) 9# 各クラスタの中心を描画する。 10axes.scatter(centroids[:, 0], centroids[:, 1], color=[ 11 'blue', 'darkred', 'green'], marker='o', lw=2) 12 13axes.set_xlabel('$x_0$') 14axes.set_ylabel('$x_1$')

イメージ説明

投稿2018/09/21 06:19

tiitoi

総合スコア21956

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

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

0

ベストアンサー

万が一ご存知でないと大変なので、念の為に申し上げておきますが、実用的なk-meansが使いたいだけならsklearn等にあります。


まず基本的に、pandasは速くはないです。

データの読み込み・書き出しだけpandasで行い、中間処理はすべてnumpyを使うのがpythonの場合はおそらくベターです。

また、データをループでなめてインデックスでアクセスするような処理も速くはないです。というか、そもそも算術演算的な処理が遅いです。

numpy・scipyの色々なテクニック、関数を活用し、できるだけベクトル演算にするか、numpy・scipyの内部で処理させるのがベターです。これらのライブラリは内部的には高速なコンパイル言語で実装されており、様々な最適化の工夫がなされているため、pythonで素直に同じアルゴリズムを書くより数桁以上速く処理できることが多いです。


余談ですが、そのコードは入出力の記述とアルゴリズムの記述が混ざっていてとても読みづらいです。

モジュール化して、綺麗にしましょう。既存のライブラリのインターフェースを参考にしてください。


以上のようなことをコードに反映させた上で、まだ速度に不満があればプロファイリングして高速化していけば良いかと思います。

投稿2018/09/21 05:57

hayataka2049

総合スコア30933

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

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

wpspring0300

2018/09/22 16:38

丁寧な回答ありがとうございました 教えていただいたことをやってみた結果実用的な速さになりました。 ありがとうございました
guest

0

処理速度に関係ないとは思いますが、ヒントになりそうなことを。

インクリメントによるインデックス指定を行っている部分は以下のように書き直せそうです。

python

1lista = [0, 1, 2, 4, 6, 10] 2for d in lista: 3 a = d * 2

また、リストデータのインデックスが欲しい場合は、 enumerate() 関数を使うと、インデックスと値を返してくれますので、以下のように書けます。

python

1a = [] 2lista = [0, 1, 2, 4, 6, 10] 3for i, d in enumerate(lista): 4 a[i] = d * 2

更に、内包表記を使うと読みにくくなるかもしれませんが、速度は上がります。
こんな感じで書きます。

python

1lista = [0, 1, 2, 4, 6, 10] 2listb = [i * 2 for i in lista] 3print(listb) 4#=> [0, 2, 4, 8, 12, 20]

参考資料

投稿2018/09/21 04:57

manzyun

総合スコア2244

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

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

0

時系列データのクラスタリングにはtslearnを使うといいようです。

参考URL
https://techblog.nhn-techorus.com/archives/6452
https://blog.brains-tech.co.jp/entry/tslearn-time-series-clustering

私は利用経験はないので何ともわかりませんが、DTWもサポートしているのでないでしょうか。

投稿2018/09/21 13:56

R.Shigemori

総合スコア3376

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問