根据另一个datafram的条件填充pandas数据帧的有效方法

2024-05-16 06:53:57 发布

您现在位置:Python中文网/ 问答频道 /正文

数据

我有一个数据帧,其中包含给定ID的排名分数:

>>> ranks
  ID  rank
0  A     6
1  B     9
2  C     6
3  D     1
4  E     1
5  F     2

我想将其转换为一个正方形矩阵,每个ID同时作为索引和列,基于以下几个条件:如果索引上的ID的秩高于列中ID的秩,则将其设置为1;如果它较低,则将其设置为0;如果相等,则将其设置为0.5;如果索引与列相同,则将其设置为np.nan。通过查看我想要的矩阵可以更好地描述这一点:

期望结果

^{pr2}$

我所做的(有效,但很慢)

下面的循环可以工作,但是对于较大的数据帧,它的速度很慢。如果有人能为我指出一个更好的、更具Python式/潘多拉式的方法来实现这一点,我希望能得到一些帮助:

# Make an empty matrix as a dataframe
mtrx = pd.DataFrame(np.zeros((len(IDs), len(IDs))), index=IDs, columns = IDs)

# Populate it via for loop
for i in IDs:
    for j in IDs:
        i_rank = ranks.loc[ranks['ID'] == i].iloc[0]['rank']
        j_rank = ranks.loc[ranks['ID'] == j].iloc[0]['rank']
        if i == j:
            mtrx.loc[i, j] = np.nan
        elif i_rank < j_rank:
            mtrx.loc[i, j] = 1.
        elif i_rank == j_rank:
            mtrx.loc[i, j] = 0.5

生成这个玩具示例的代码

import pandas as pd
import numpy as np
np.random.seed(1)
IDs = list('ABCDEF')
ranks = pd.DataFrame({'ID':IDs, 'rank':np.random.randint(1,10,len(IDs))})

Tags: 数据ididsdataframeforlenasnp
1条回答
网友
1楼 · 发布于 2024-05-16 06:53:57

numpy方法

s=ranks['rank'].values
s1=(s>s[:,None]).astype(int).astype(float)
s1[s==s[:,None]]=0.5
s1[[np.arange(len(s))]*2] = np.nan
pd.DataFrame(s1,index=ranks.ID,columns=ranks.ID)


Out[843]: 
ID    A    B    C    D    E    F
ID                              
A   NaN  1.0  0.5  0.0  0.0  0.0
B   0.0  NaN  0.0  0.0  0.0  0.0
C   0.5  1.0  NaN  0.0  0.0  0.0
D   1.0  1.0  1.0  NaN  0.5  1.0
E   1.0  1.0  1.0  0.5  NaN  1.0
F   1.0  1.0  1.0  0.0  0.0  NaN

熊猫接近

^{pr2}$

相关问题 更多 >