gpt4 book ai didi

python - 有没有一种优雅的方法可以只保留矩阵中每一行的 top[2~3] 值?

转载 作者:太空狗 更新时间:2023-10-30 00:58:54 25 4
gpt4 key购买 nike

A easier way has updated in the end of the question.

我有什么

我有一个名为matrixcorr_of_user用户-用户 相关矩阵,如下所示:

userId       316       320       359       370       910
userId
316 1.000000 0.202133 0.208618 0.176050 0.174035
320 0.202133 1.000000 0.242837 0.019035 0.031737
359 0.208618 0.242837 1.000000 0.357620 0.175914
370 0.176050 0.019035 0.357620 1.000000 0.317371
910 0.174035 0.031737 0.175914 0.317371 1.000000

我想要什么

For every user, I just want to keep the 2 other users that are the most similar to him (the highest correlation values per row after excluding the elements of the diagonal). Like so:

Out[40]: 
userId 316 320 359 370 910
corr_user
316 NaN 0.202133 0.208618 NaN NaN
320 0.202133 NaN 0.242837 NaN NaN
359 NaN 0.242837 NaN 0.357620 NaN
370 NaN NaN 0.357620 NaN 0.317371
910 NaN NaN 0.175914 0.317371 NaN

我知道如何实现它,但是我想出的方法太复杂了。 谁能提供更好的主意?

我尝试过的

我首先融化矩阵:

melted_corr = corr_of_user.reset_index().melt(id_vars ="userId",var_name="corr_user")

melted_corr.head()
Out[23]:
userId corr_user value
0 316 316 1.000000
1 320 316 0.202133
2 359 316 0.208618
3 370 316 0.176050
4 910 316 0.174035

逐行过滤:

get_secend_third = lambda x : x.sort_values(ascending =False).iloc[1:3]

filted= melted_corr.set_index("userId").groupby("corr_user")["value"].apply(get_secend_third)

filted
Out[39]:
corr_user userId
316 359 0.208618
320 0.202133
320 359 0.242837
316 0.202133
359 370 0.357620
320 0.242837
370 359 0.357620
910 0.317371
910 370 0.317371
359 0.175914

最后 reshape 它:

filted.reset_index().pivot_table("value","corr_user","userId")
Out[40]:
userId 316 320 359 370 910
corr_user
316 NaN 0.202133 0.208618 NaN NaN
320 0.202133 NaN 0.242837 NaN NaN
359 NaN 0.242837 NaN 0.357620 NaN
370 NaN NaN 0.357620 NaN 0.317371
910 NaN NaN 0.175914 0.317371 NaN

更新:

在看到@John Zwinck 的回答后,我想出了一个更简单的方法来做到这一点

假设有一个新矩阵 df 具有一些重复值和 NaN

userId  316       320       359       370       910
userId
316 1.0 0.500000 0.500000 0.500000 NaN
320 0.5 1.000000 0.242837 0.019035 0.031737
359 0.5 0.242837 1.000000 0.357620 0.175914
370 0.5 0.019035 0.357620 1.000000 0.317371
910 NaN 0.031737 0.175914 0.317371 1.000000

首先我得到每一行的rank

rank = df.rank(1, ascending=False, method="first")

然后我使用 df.isin() 获得我想要的掩码。

mask = rank.isin(list(range(2,4)))

最后

df.where(掩码)

然后我得到我想要的。

userId  316  320       359       370  910
userId
316 NaN 0.5 0.500000 NaN NaN
320 0.5 NaN 0.242837 NaN NaN
359 0.5 NaN NaN 0.357620 NaN
370 0.5 NaN 0.357620 NaN NaN
910 NaN NaN 0.175914 0.317371 NaN

最佳答案

首先,使用 np.argsort() 查找具有最高值的位置:

sort = np.argsort(df)

这给出了一个 DataFrame,它的列名是无意义的,但从右边数第二和第三列在每行中包含所需的索引:

        316  320  359  370  910
userId
316 4 3 1 2 0
320 3 4 0 2 1
359 4 0 1 3 2
370 1 0 4 2 3
910 1 0 2 3 4

接下来,构造一个 bool 掩码,在上面的位置设置为真:

mask = np.zeros(df.shape, bool)
rows = np.arange(len(df))
mask[rows, sort.iloc[:,-2]] = True
mask[rows, sort.iloc[:,-3]] = True

现在你有了你需要的面具:

array([[False,  True,  True, False, False],
[ True, False, True, False, False],
[False, True, False, True, False],
[False, False, True, False, True],
[False, False, True, True, False]], dtype=bool)

最后,df.where(mask):

             316       320       359       370       910
userId
316 NaN 0.202133 0.208618 NaN NaN
320 0.202133 NaN 0.242837 NaN NaN
359 NaN 0.242837 NaN 0.357620 NaN
370 NaN NaN 0.357620 NaN 0.317371
910 NaN NaN 0.175914 0.317371 NaN

关于python - 有没有一种优雅的方法可以只保留矩阵中每一行的 top[2~3] 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47434924/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com