python 直方图排序_python - 如何在二维分类直方图中对轴进行排序以最大化聚类 - 堆栈内存溢出...

我正在绘制分类数据的二维热图直方图,以帮助显示和解释大型数据集中的模式,而且我不知道一种有效地沿每个轴对值进行有效排序的方法,以便相关值彼此相邻出现。

使用PyPI下载日志中的示例(仅包含4个项目),我可以绘制项目名称与文件名称的直方图:

(请注意,我停在60个最常见的不同值,然后将其他所有值都合并到一个(其他)列中)

在这个极端的示例中,每个文件名都只与一个项目相关联,因此,如果对x值进行重新排序以使所有numpy文件彼此相邻,然后紧跟熊猫文件等...

在我的情况下,我不能保证x轴或y轴将包含更强的类别组,因此我希望找到可以沿两个轴排序的解决方案。 我还处理最大60x60的直方图,并且进行这种排序的时间预算小于500毫秒(理想情况下)。

关于正确解决方案的思考

我认为答案在于:

为所有(x,y)组合创建链接图

在链接图上运行分层聚类

基于集群的某种形式的排序。

我不清楚如何使用分层群集对每个轴重新排序。

使用相关矩阵的类似示例可以有效地处理一维数据,并将其转换为二维似乎很棘手。

当前的天真的实现

我当前的方法(某种程度上较差)是为表定义一个能量函数,该函数将各列与下一列之间的每个值的绝对差之和:

def get_energy(values):

np.abs(values[:, :-1] - values[:, 1:]).sum()

然后,对于每一行,我将计算必须交换哪些列以最终对该行中的值进行排序(相对于该行中的最高值)。 然后,对于每个交换,我都会计算交换前后的表能量。 如果能量较低,则使用交换的值更新我的表,然后继续。

最后,我转置表格,并重复以上步骤。

这种方法存在严重缺陷,因为天真的交换方法不会移动整个列,并且每个轴之间的订单之间也没有协作,因此您最终只能将我描述为零碎的内容当发生在第2列的交换发生时。破坏第1列中的值:

一个使用来自同一数据集的不同数据,比较发行版名称与发行版版本的示例(请注意,我在这里进行了一些轴标准化,否则Ubuntu将主导一切!):

未排序:

使用以上方法:

我当前的代码如下所示:(获取一个熊猫表,对numpy ndarrays进行操作):

class Reorderer:

def __init__(self, table):

self.table = table.values

self.rows = table.index.values

self.cols = table.columns.values

def get_frame(self):

return pd.DataFrame(data=self.table, index=self.rows, columns=self.cols)

def _energy(self, values):

return np.abs(values[:, :-1] - values[:, 1:]).sum()

def _get_proposals(self, row_num):

row = self.table[row_num]

swaps = row.argsort()[::-1]

basis = swaps[0]

for order, from_index in enumerate(swaps[1:], 1):

if row[from_index] == 0:

break

to_index = basis + order

if to_index >= len(self.cols):

to_index = basis - order

if from_index != to_index:

yield (from_index, to_index)

def reorder(self):

initial_swaps = self.table[0].argsort()[::-1]

self.table = self.table[:, initial_swaps]

self.cols = self.cols[initial_swaps]

for row_num in range(1, len(self.rows)):

current_energy = self._energy(self.table[:row_num+1])

for proposed_from, proposed_to in self._get_proposals(row_num):

new_order = np.arange(len(self.cols))

new_order[proposed_from] = proposed_to

new_order[proposed_to] = proposed_from

reordered = self.table[:, new_order]

new_energy = self._energy(reordered[:row_num+1])

if new_energy < current_energy:

self.table = reordered

self.cols = self.cols[new_order]

current_energy = new_energy

return self.get_frame()

必须有一个更好的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值