Переупорядочьте столбцы и строки тепловой карты Holoviews на основе показателя сходства (например, косинусное сходство и т. Д.) - PullRequest
1 голос
/ 22 марта 2019

Я был удивлен, что никто, кажется, не спрашивал об этом раньше.

Предполагая, что у меня есть фрейм данных pandas (случайный пример), я могу получить тепловую карту с Holoviews и рендерингом Bokeh:

rownames = 'ABCDEFGHIJKLMNO'
df = pd.DataFrame(np.random.randint(0,20,size=(20, len(rownames))), columns=list(rownames))
hv.HeatMap({'x': df.columns, 'y': df.index, 'z': df}, 
           kdims=[('x', 'Col Categories'), ('y', 'Row Categories')], 
           vdims='z').opts(cmap="viridis", width=520, height=520)

enter image description here

Данные (x и y) являются категориальными, поэтому начальный порядок строк или столбцов не имеет значения. Я хотел отсортировать строки / столбцы по некоторому показателю сходства.

Один из способов - использовать кластерную карту seaborn:

heatmap_sns = sns.clustermap(df, metric="cosine", standard_scale=1, method="ward", cmap="viridis")

Вывод выглядит так: enter image description here

Столбцы и строки были упорядочены по сходству (в данном случае косинус основан на точечном произведении; доступны другие, например, «корреляция» и т. Д.).

Однако я хочу отобразить кластерную карту в Holoviews. Как обновить порядок исходного кадра данных из матрицы seaborn?

Ответы [ 2 ]

1 голос
/ 28 июня 2019

Более чистый подход к ответу Алекса (т. Е. Это был принятый ранее ответ) заключается в использовании свойства data2d возвращенного объекта из функции sns.clustermap().Это свойство содержит переупорядоченные данные (т.е. данные после кластеризации).Итак:

df_ro = heatmap_sns.data2d  

заменяет все следующие строки:

# get col and row names by ID
colname_list = [df.columns[col_id] for col_id in 
heatmap_sns.dendrogram_col.reordered_ind]
rowname_list = [df.index[row_id] for row_id in 
heatmap_sns.dendrogram_row.reordered_ind]
# update dataframe
df_ro = df.reindex(rowname_list)
df_ro = df_ro[colname_list]
1 голос
/ 22 марта 2019

Можно получить доступ к индексам переупорядоченных столбцов / строк из кластерной карты seaborn, используя:

> print(f'rows: {heatmap_sns.dendrogram_row.reordered_ind}')
> print(f'columns: {heatmap_sns.dendrogram_col.reordered_ind}')
rows: [5, 0, 13, 2, 18, 7, 4, 16, 12, 19, 14, 15, 10, 3, 8, 6, 17, 11, 1, 9]
columns: [7, 1, 10, 5, 9, 0, 8, 13, 2, 6, 14, 3, 4, 11, 12]

Чтобы обновить порядок строк / столбцов исходного кадра данных:

# get col and row names by ID
colname_list = [df.columns[col_id] for col_id in heatmap_sns.dendrogram_col.reordered_ind]
rowname_list = [df.index[row_id] for row_id in heatmap_sns.dendrogram_row.reordered_ind]
# update dataframe
df_ro = df.reindex(rowname_list)
df_ro = df_ro[colname_list]

Я сделал это здесь, сначала получив имена, возможно, есть даже прямой способ обновить столбцы / строки по индексам.

hv.HeatMap({'x': df_ro.columns, 'y': df_ro.index, 'z': df_ro}, 
           kdims=[('x', 'Col Categories'), ('y', 'Row Categories')], 
           vdims='z').opts(cmap="viridis", width=520, height=520)

Поскольку я использовал случайные данные, в категориях есть небольшой порядок, новсе же картина выглядит чуть менее шумной.Обратите внимание на то, что ось holoviews / df y является просто обратной по сравнению с матрицей-матрицей морского происхождения, поэтому графика выглядит перевернутой.

enter image description here

...