【问题标题】:Pandas correlation matrix to dictionary of unique index/column combinationsPandas 与唯一索引/列组合字典的相关矩阵
【发布时间】:2020-04-17 22:54:50
【问题描述】:

我正在 Pandas 上使用这个数据集,目前我被困在这一步:

我有一个如下所示的数据框:

     id1   id2   id3   id4
id1   1    0.3   0.5   0.2
id2  0.2    1    0.4   0.7
id3   0    0.5    1    0.8
id4  0.6   0.1    0     1

现在,id<num> 指的是与每条消息关联的post_id。上面的余弦相似度矩阵是一个二维数组,我做了一些工作来找到这些不同消息之间的余弦相似度分数。

最终目标是在 UI 上显示并聚合看起来彼此相似的帖子。为此,我需要id1id2id1id3 等中的分数概览。

但是,我现在有一个 1 的对角线(这是有道理的,因为它们是相同的),但是我怎样才能以更好的方式做到这一点,这样我就不必使用双循环,并最终带来它到我可以在数据框中显示如下的状态。

我目前正在做的事情给了我这个:

id1, id1, score
id1, id2, score
id1, id3, score
id1, id4, score
id2, id1, score
id2, id2, score
id2, id3, score
id2, id4, score
id3, id4, score
id3, id1, score
id3, id2, score
id3, id3, score
id4, id1, score
id4, id2, score
id4, id3, score
id4, id4, score

我想得到的是这样的:

id1, id2, score
id1, id3, score
id1, id4, score
id2, id3, score
id2, id4, score
id3, id4, score

我怎样才能做到这一点?我应该将二维矩阵重塑为数组吗?我觉得我在这里遗漏了一些东西。

感谢您在此问题上的帮助。

【问题讨论】:

标签: python pandas


【解决方案1】:

您可以在数据框的上三角部分插入NaNs stack 以删除那些NaNs 并从pd.Series.iteritems 返回的迭代器构建一个字典:

a = df.values
a[np.tril_indices(a.shape[0], 0)] = np.nan
df[:] = a # or directly create a new one -> pd.Dat...(a, index=df.index...)
out = dict(df.stack().iteritems())

print(out)
{('id1', 'id2'): 0.3,
 ('id1', 'id3'): 0.5,
 ('id1', 'id4'): 0.2,
 ('id2', 'id3'): 0.4,
 ('id2', 'id4'): 0.7,
 ('id3', 'id4'): 0.8}

注意与

a = df.values
a[np.tril_indices(a.shape[0], 0)] = np.nan

你忽略了你已经拥有的相似之处:

print(a)

[[nan 0.3 0.5 0.2]
 [nan nan 0.4 0.7]
 [nan nan nan 0.8]
 [nan nan nan nan]]

因此,通过更新数据框和堆叠,您最终会得到感兴趣的组合:

df[:] = a
df.stack()

id1  id2    0.3
     id3    0.5
     id4    0.2
id2  id3    0.4
     id4    0.7
id3  id4    0.8
dtype: float64 

【讨论】:

  • 谢谢!非常清楚,完全忘记了所有 NxN 矩阵都是对称的!
  • 相关矩阵是 :) @bryancresswell
【解决方案2】:

你可以试试stack:

out = df.stack() \ 
        .reset_index() \ 
        .rename(columns={"level_0": "col1", "level_1": "col2", 0: "score"})
out = out[out.col1 != out.col2]

输出

print(out)
#    col1 col2  score
# 1   id1  id2    0.3
# 2   id1  id3    0.5
# 3   id1  id4    0.2
# 4   id2  id1    0.2
# 6   id2  id3    0.4
# 7   id2  id4    0.7
# 8   id3  id1    0.0
# 9   id3  id2    0.5
# 11  id3  id4    0.8
# 12  id4  id1    0.6
# 13  id4  id2    0.1
# 14  id4  id3    0.0

解释

  • 使用stack 将所有值堆叠在一列中:
print(df.stack())
# id1  id1    1.0
#      id2    0.3
#      id3    0.5
#      id4    0.2
# id2  id1    0.2
#      id2    1.0
#      id3    0.4
#      id4    0.7
# id3  id1    0.0
#      id2    0.5
#      id3    1.0
#      id4    0.8
# id4  id1    0.6
#      id2    0.1
#      id3    0.0
#      id4    1.0
  • 使用reset_index重置索引
  • 使用rename重命名列
  • 过滤输出以删除值 col1 等于 col2

【讨论】:

  • 是否有理由不将右上角的三角形归零?这种流程效率更高吗?我还想知道,out = out[out.col1 != out.col2], won't id2` 和 id1 上是否仍然存在于 out 数据框中?在这种情况下,由于id1id2 相同,所以会有重复。
【解决方案3】:

试试这个:

1) 将数据帧乘以 numpy.tril(df.shape) - 调整 tril 参数以将表格中不需要的部分归零

2) pandas.melt() 数据帧到所需格式

3) 过滤掉带零的行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多