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

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

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

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

Q&A

解決済

2回答

1461閲覧

csv中の列を凡例としてグラフ内に表示したい

K-Shape

総合スコア1

Python

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

0グッド

0クリップ

投稿2020/06/05 01:02

編集2020/06/05 02:12
Python 3.6.4およびtslearnを使用して、経時データのK-Shapeによるクラスタリングを行っています。 一つのグラフ中の複数のサンプルの凡例を示したいです。 グラフの呼び出し元ファイルはcsvで、各サンプル名、時間とその時のデータの値を3列で表記しています。 csv中のNameを凡例として表示したいです。 csv例 Name Time Value 1 12 0.5 1 18 1.2 2 12 0.8 2 18 2.2 ・・・・・ ### 該当のソース
def read_file_to_dataframe(filenames): dfs = [] for filename in filenames: original_df = pd.read_csv(filename, index_col=None, header=0) dfs.append(original_df) return dfs def time_series_data_to_array(dataframes, target_col=''): tsdata = [] for i, df in enumerate(dataframes): tsdata.append(df[target_col].values.tolist()[:]) len_max = 0 for ts in tsdata: if len(ts) > len_max: len_max = len(ts) for i, ts in enumerate(tsdata): len_add = len_max - len(ts) tsdata[i] = ts + [ts[-1]] * len_add tsdata = np.array(tsdata) return tsdata def transform_vector(time_series_array): stack_list = [] for j in range(len(time_series_array)): data = np.array(time_series_array[j]) data = data.reshape((1, len(data))).T stack_list.append(data) stack_data = np.stack(stack_list, axis=0) return stack_data
df2=read_1file_to_dataframe('sample_data.csv')
tsdata = time_series_data_to_array(dataframes=df2, target_col='data') stack_data = transform_vector(time_series_array=tsdata)
plt.figure(figsize=(16,9)) for yi in range(2): plt.subplot(2, 1, 1 + yi) for xx in stack_data[y_pred == yi]: plt.plot(xx.ravel(),"-k", alpha=.2) plt.title("Cluster %d" % (yi + 1)) plt.legend(loc="upper right") plt.tight_layout() plt.show()

以上、宜しくお願い致します。

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

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

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

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

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

jeanbiego

2020/06/05 01:21

コードは<code>機能を使って書いてもらえると、読みやすくなって回答が集まるかと。
K-Shape

2020/06/05 01:32

親切に教えて頂き有難うございます。 修正させて頂きました。
magichan

2020/06/05 02:02

グラフの描画に使用されております stack_data がどのような形式のデータかを教えていただけませんか。
K-Shape

2020/06/05 02:12

有難うございます。 追記した部分で判断可能でしょうか?
magichan

2020/06/05 03:16

せっかく追加していただいたのですが、 plt.figure(figsize=(16,9)) の前の行あたりで print(stack_data) を行ってみて、その結果を貼っていただけると助かります。 (データの形式が知りたいだけなので、途中省略をしたり、見せたくないデータを加工しても構いません )
K-Shape

2020/06/05 03:29 編集

承知致しました。 以下の通り実行致しました。 seed = 0 np.random.seed(seed) stack_data = TimeSeriesScalerMeanVariance(mu=0.0, std=1.0).fit_transform(stack_data) ks = KShape(n_clusters=3, n_init=10, verbose=True, random_state=seed) y_pred = ks.fit_predict(stack_data) print(stack_data) plt.figure(figsize=(16,9)) for yi in range(3): plt.subplot(3, 1, 1 + yi) for xx in stack_data[y_pred == yi]: plt.plot(xx.ravel(),"-k", alpha=.2) plt.title("Cluster %d" % (yi + 1)) plt.legend(loc="upper right") plt.tight_layout() plt.show() <結果> Init 1 0.009 --> Resumed because of empty cluster Init 1 0.008 --> 0.009 --> Init 2 0.015 --> Resumed because of empty cluster Init 2 0.010 --> 0.009 --> 0.016 --> Init 3 Resumed because of empty cluster Init 3 Resumed because of empty cluster Init 3 0.004 --> 0.007 --> Init 4 Resumed because of empty cluster Init 4 No handles with labels found to put in legend. 0.007 --> 0.003 --> 0.007 --> Init 5 0.009 --> Resumed because of empty cluster [[[ 1.00893576] [ 2.30745985] [ 2.95674218] [ 2.30745985] ......(以下同様の数列) +グラフ
guest

回答2

0

ベストアンサー

やっと内容を理解しました。
なんかやりたい事に対して、かなーり冗長な処理を行っている気がします。

質問のようなCSVデータにおいて、各NameにおけるTimeの種類全て同じであるならば、DataFrame.pivot() を使って

Python

1df = pd.read_csv('data.csv') 2pivot_df = df.pivot(index='Name', columns='Time',values='Value') 3stack_data = TimeSeriesScalerMeanVariance(mu=0.0, std=1.0).fit_transform(pivot_df.values) 4ks = KShape(n_clusters=3, n_init=10, verbose=True, random_state=seed) 5y_pred = ks.fit_predict(stack_data)

で良いのではないでしょうか。
この方法であれば、データがListではなく DataFrame形式になっているので、DataFrame.plot() でグラフを描画することで簡単に凡例を書くことができます。

以下は動作サンプルです。

data.csv

CSV

1Name,Time,Value 21,12,0.5 31,18,1.2 41,24,2.5 52,12,3.4 62,18,2.1 72,24,2.3 83,12,4.5 93,18,1.0 103,24,2.0 114,12,3.2 124,18,0.8 134,24,1.9 145,12,3.2 155,18,0.8 165,24,1.9 176,12,0.8 186,18,3.8 196,24,1.5

ソース

Python

1import pandas as pd 2import matplotlib.pyplot as plt 3from tslearn.clustering import KShape 4from tslearn.preprocessing import TimeSeriesScalerMeanVariance 5 6seed = 0 7df = pd.read_csv('data.csv') 8pivot_df = df.pivot(index='Name', columns='Time',values='Value') 9stack_data = TimeSeriesScalerMeanVariance(mu=0.0, std=1.0).fit_transform(pivot_df.values) 10ks = KShape(n_clusters=3, n_init=10, verbose=True, random_state=seed) 11y_pred = ks.fit_predict(stack_data) 12 13fig, axs = plt.subplots(3, 1, figsize=(16,9)) 14for i, ax in enumerate(axs): 15 pivot_df[y_pred == i].T.plot(ax=ax) 16 plt.title(f"Cluster {i+1}") 17 18plt.legend(loc="upper right") 19plt.tight_layout() 20plt.show()

結果
イメージ説明

投稿2020/06/05 04:34

編集2020/06/05 04:35
magichan

総合スコア15898

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

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

K-Shape

2020/06/05 04:45

まさに得たいグラフそのものです。 初心者で困っていましたので大変助かりました。 有難うございました。
guest

0

コードに抜けが多くてコピペで動かないので試せてませんが、以下のようにplotの引数にlabelを指定してあげるのではいかがでしょうか。

python3

1for yi in range(2): 2 plt.subplot(2, 1, 1 + yi) 3 for xx in stack_data[y_pred == yi]: 4 name = df2.at[df2.index[yi],"Name"] 5 plt.plot(xx.ravel(),"-k", alpha=.2, label=str(name)) 6 plt.title("Cluster %d" % (yi + 1))

投稿2020/06/05 02:07

jeanbiego

総合スコア3966

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

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

K-Shape

2020/06/05 02:38 編集

有難うございます。抜けが多くて申し訳ありません。 以下のエラーが出てしまいました。 File "<ipython-input-11-9879337ed9db>", line 21 name = df2.at[df2.index[yi],"Name"] ^ SyntaxError: invalid character in identifier
jeanbiego

2020/06/05 02:32

全角の文字とか空白とか何か混ざってませんでしょうか。
K-Shape

2020/06/05 02:38

name = df2.at[df2.index[yi],"Name"] この文字列のままです。もとのcsv fileの列名も”Name"で間違いないようです。
jeanbiego

2020/06/05 02:55

その文字列の前後をチェックしてみてください。括弧が足りないとか全角文字が使われているとか、そういうときにでるエラーです。
K-Shape

2020/06/05 03:14 編集

ありがとうございます。文字列の前後の空白を調整して実行したところ、SyntaxError: invalid character in identifierはでなくなりましたが、今後は以下のエラーとなりました。 listとDataFrameの問題でしょうか? AttributeError Traceback (most recent call last) <ipython-input-42-76bdb7ccf996> in <module>() 19 plt.subplot(3, 1, 1 + yi) 20 for xx in stack_data[y_pred == yi]: ---> 21 name = df2.at[df2.index[yi],"Name"] 22 plt.plot(xx.ravel(),"-k", alpha=.2, label=str(name)) 23 #plt.plot(ks.cluster_centers_[yi].ravel(), "r-") AttributeError: 'list' object has no attribute 'at'
jeanbiego

2020/06/05 03:47

df2がlistになっているみたいですね。どこかでDataFrameからlistに置き換えていますか?
K-Shape

2020/06/05 03:53

csvを読み込む以前の部分に以下のコードがあります。 この部分でlistに置き換わっているでしょうか? def time_series_data_to_array(dataframes, target_col=''): tsdata = [] for i, df in enumerate(dataframes): tsdata.append(df[target_col].values.tolist()[:]) len_max = 0 for ts in tsdata: if len(ts) > len_max: len_max = len(ts) for i, ts in enumerate(tsdata): len_add = len_max - len(ts) tsdata[i] = ts + [ts[-1]] * len_add tsdata = np.array(tsdata) return tsdata def transform_vector(time_series_array): stack_list = [] for j in range(len(time_series_array)): data = np.array(time_series_array[j]) data = data.reshape((1, len(data))).T stack_list.append(data) stack_data = np.stack(stack_list, axis=0) return stack_data
jeanbiego

2020/06/05 04:09

デバッグして確かめるか、print(type(df2))を各所に仕込んで確認してみてください。
K-Shape

2020/06/05 04:46 編集

根気強く教えて頂き有難うございました。 magichanのご回答と併せて、希望の結果を得ることが出来ました。 大変助かりました。 今後は、デバックやprint(type( ))を用いた方法で解決策を探ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問