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

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

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

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

1295閲覧

同時刻の同IDのデータをクラスタリングしたい

mi2

総合スコア63

DateTime

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2019/10/29 14:18

編集2019/11/05 02:14

考えていること

IDデータ、時間データ、複数特徴量データを用いて、同時刻の同一IDで絞った上でクラスタリングをかけ、
クラスタ数とクラスタ間距離とデンドログラムを取得したいです。
例えば、下記のようなデータがあったとします。

データ

同一IDで見て、同時刻なものは idがaの場合、16:03の3データと16:04の3データ、 idがbの場合、16:04の3データで、作成したいデータフレームは以下になります。 # 作成したいデータフレーム

id time a b
a 2019-01-04 16:03:00 1 None
a 2019-01-04 16:04:00 4 10.5
b 2019-01-04 16:04:00 3 20.1
:

# 試したこと 任意のdfに対して以下のコードで、クラスタ数とデンドログラムは取得できます・ # 困っていること ・ID/時間ごとに ・クラスタ間 大変恐縮ではございますが、お知恵を拝借できましたら幸いです。 何卒よろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

DataFrame.groupby().apply() にて関数を呼び出し、その関数内でグループ毎のクラスタ数・クラスタ間距離を求めて pandas.Series() データとして返すことで実現できます。

クラスター間距離を求めるコードがありませんでしたので、下のコードでは しきい値として使った値をクラスター間距離として扱っております。

Python

1import pandas as pd 2import io 3from scipy.cluster.hierarchy import linkage, dendrogram, fcluster 4import numpy as np 5 6data = """ 7id,time,feature1,feature2,feature3 8a,2019-01-04 16:03:00,14,32,88 9a,2019-01-04 16:03:00,12,21,16 10a,2019-01-04 16:03:00,13,15,44 11a,2019-01-04 16:04:00,11,36,45 12a,2019-01-04 16:04:00,13,15,44 13a,2019-01-04 16:04:00,18,35,53 14b,2019-01-04 16:04:00,17,21,36 15b,2019-01-04 16:04:00,19,93,23 16b,2019-01-04 16:04:00,25,27,55 17""" 18 19df = pd.read_csv(io.StringIO(data),parse_dates=['time']) 20 21def f(d): 22 linkage_result = linkage(d, method='ward', metric='euclidean') 23 # クラスタ分けのためのしきい値の設定 24 threshold = 0.8 * np.max(linkage_result[:, 2]) 25 # クラスタリング結果の値を取得 26 clustered = fcluster(linkage_result, threshold, criterion='distance') 27 # 結果をSeriesデータとして返す(クラスタ間距離はしきい値で良いの??) 28 return pd.Series({'クラスタ数': np.max(clustered), 'クラスタ間距離': threshold}) 29 30 31# groupby.apply() にて関数 f() を呼び出す 32r = df.groupby(['id','time'])[['feature1','feature2','feature3']].apply(f) 33print(r) 34# クラスタ数 クラスタ間距離 35#id time 36#a 2019-01-04 16:03:00 2.0 55.134260 37# 2019-01-04 16:04:00 2.0 19.541409 38#b 2019-01-04 16:04:00 2.0 67.068125

投稿2019/10/30 02:08

magichan

総合スコア15898

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

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

mi2

2019/10/30 23:36 編集

ありがとうございます!!
mi2

2019/10/31 01:05

すみません、レコード数が1の場合、ValueError: The number of observations cannot be determined on an empty distance matrix.となってしまうのですが、この例外は関数内で処理した方がよいのでしょうか。
magichan

2019/10/31 01:34

その方が良いでしょうね。 関数の最初にデータ数を確認して1の場合は処理はせずに return pd.Series({'クラスタ数': 0, 'クラスタ間距離': np.nan}) 等の値を返すと良いかと思います
magichan

2019/10/31 01:36

あっ return pd.Series({'クラスタ数': 1, 'クラスタ間距離': np.nan}) の方が良いのかな(このあたりはお好みで)
mi2

2019/10/31 02:58 編集

if x == 1: return pd.Series({'クラスタ数': 1, 'dist': クラスタ間距離}) else: linkage_result以降の処理・・・ のようなイメージなのですが、 > 関数の最初にデータ数を確認して1の場合は処理はせず はdのlenを見に行く感じでしょうか。 初心者でこのあたりの処理をサクサク書けずご迷惑おかけして申し訳ございません。
magichan

2019/10/31 02:51

関数(f)の一番最初に if len(d) == 1: __return pd.Series({'クラスタ数': 1, 'dist': クラスタ間距離}) を追加するとよいのではないでしょうか
mi2

2019/10/31 02:59

ありがとうございます。 すみません間違えてました。 valueerrorを捕まえに行くことで例外処理しました。 ご丁寧にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問