【问题标题】:Python Getting second largest element in each row of matrixPython在矩阵的每一行中获取第二大元素
【发布时间】:2017-08-14 23:15:13
【问题描述】:

我从一个相关矩阵开始,这意味着第 i,j 个条目将是第 i 个元素和第 j 个元素之间的相关性(所以对角线为 1)。我试图找到每个元素与另一个元素的最大相关性(不包括自身,因为 1 的列表对我的情况没有帮助)。

1    0.7  0.4  0.1
0.7  1    0.3  0.2
0.4  0.3  1    0.5
0.1  0.2  0.5  1

假设我有上面的矩阵。我想要类似的东西
(最大相关性,第 i 个元素,第 j 个元素)。在上面的矩阵中,我想得到
[(0.7, 0, 1), (0.7, 1, 0), (0.5, 2, 3), (0.5, 3, 2)]
因此。

什么是解决这个问题的好方法?
我将矩阵作为熊猫数据框。索引和列具有相同的名称,现在说[0, 1, 2, 3]。目前我只想做类似的事情

D = {}
for i in df.columns:
    max = (0, 0, 0)
    for j in df.columns:
        if i==j:
           continue
        element = df.loc[i,j]
        if element > max[0]:
           max = (element, i, j)
    D[i] = max

这可以做得更好/更快吗?是否有内置方法可以改进?

【问题讨论】:

  • 你有没有想出解决这个问题的方法?请分享您尝试过的内容。重要的是你分享和展示你的努力,因为这就是你学习最好的方式,这就是它应该如何出现在 stackoverflow 上。解决这个问题的一个好方法是:问题 > 你的努力 > 问题和其他细节。研究工作是强制性的。祝你好运。
  • 嗨!谢谢你的回复。我一直在考虑逐行循环(使用嵌套的for 循环),然后检查哪个元素是第二大的,但这似乎效率低下。
  • 遍历每一列也可以,因为矩阵是对称的。我试图不对它进行排序,因为我想获得最高相关性的原始索引。
  • 无论您想出什么,都将其编码并添加到您的问题中。是的,嵌套 for 循环会很讨厌,因为它们本质上是二次的。试着划分你的问题,试着想出一些本质上递归的东西。最后,如果您没有想到其他任何事情,请使用嵌套循环并将它们添加到您的问题中。
  • 如果您使用相同的逻辑则不会:如果您尝试以相同的方式做同样的事情,唯一的区别是使用递归调用而不是循环。当我要求您尝试提出本质上递归的方法时,我的意思是考虑将问题划分(也称为分而治之的方法),而使用循环是不可能的。一个很好的例子是具有 O(nlogn) 的合并排序算法,任何本质上的迭代至少是 O(n^2)。是的,我确实看到您添加了代码,但只是在添加了我的评论之后,这就是我对您的帖子投赞成票的原因。

标签: arrays algorithm python-2.7 matrix multidimensional-array


【解决方案1】:

所以我最终使用了一些想法,将两个答案(来自 Michael 和 kraskevich)的对角线更改为一些相对较小的值,如 -1,但使用不同的方法。

maxCors = dfFinalCor.apply(lambda x: (max(x), x.idxmax(), x.name)).tolist()

给我我需要的东西:)
另外,我觉得apply 在这里工作得很好。 (我不知道为什么,但我不喜欢使用 zip,除非必须)

【讨论】:

    【解决方案2】:

    试试这个:

    import numpy as np
    
    c = np.array([[1. ,  0.7,  0.4,  0.1],
                  [0.7,  1. ,  0.3,  0.2],
                  [0.4,  0.3,  1. ,  0.5],
                  [0.1,  0.2,  0.5,  1. ]])
    c -= np.eye(c.shape[0])  # remove the 1 on diagonal
    result = np.array([[np.max(row), num_row, np.argmax(row)] for num_row, row in enumerate(c)])
    

    根据我对相关性的理解,我假设您始终在某个对称实值二次相关矩阵 c 的对角线上具有该值 1,并且您不关心这个对角线入口,所以我只是取消它。我接下来要做的是迭代列表理解中相关矩阵的所有行。对于每一行,我分别用np.maxnp.argmax 找到最大值和最大值的索引,这给出了你想要的结果。如果您不想使用数组,则可以改用 result = [(np.max(row), num_row, np.argmax(row)) for num_row, row in enumerate(c)](或根据@kraskevich result = list(zip(np.max(c, axis=1), np.arange(c.shape[0]), np.argmax(c, axis=1))) 的解决方案),它会产生您预期的输出。

    【讨论】:

    • 我认为将对角线上的值设置为小于-1而不等于0会更安全,因为相关系数可以为负。
    • 我不知道。在那种情况下,你是对的。无论如何,使用相关矩阵的副本而不是覆盖对角线值可能会更好。
    【解决方案3】:

    首先,您可以使用小于任何相关系数的值填充对角线。有一个标准的numpy 函数可以做到这一点:

    np.fill_diagonal(df.values, -2.)
    

    之后,您只需要在每一列中找到最大值及其索引(DataFrame 具有计算两者的方法)并压缩结果:

    list(zip(df.max(), df.columns, df.idxmax()))
    

    【讨论】:

    • 只是为了确保我理解,这个解决方案按列迭代,而迈克尔按行迭代?他们如何比较性能?
    • 是的,它遍历引擎盖下的列(如果不查看所有元素,就不可能找到最大值)。比较性能的最佳方法是根据您需要的数据测量两种解决方案的时间(我没有这样做)。
    猜你喜欢
    • 1970-01-01
    • 2021-02-15
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多