询问一下排序问题的python 实现方式

现在有原始数据 ID (ID 有几千个)和每个ID的评分 如图所示

img

现在要实现如下排序功能,就是用每个ID跟其余的ID依次进行成对比较: 如图所示

img

前一个ID比后一个ID的得分高则对比结果是1,得分相同为0, 得分低的话输出结果为-1

因为ID 有几百个,所以需要一个通用的代码。最后输出的是这个对比结果的list.

改下你自己的路径 ,path1,path2 ,其他不用动


import pandas as pd
from itertools import combinations

path1='D:/aaa.csv'   #输入数据路径
path2='D:/bbb.csv'   #导出数据路径


df1=pd.read_csv(path1)
zh=list(combinations(df1.ID,2))
res=[]
for i in zh:
    v1=float(df1[df1.ID==i[0]].Score)
    v2=float(df1[df1.ID==i[1]].Score)
    if v1>v2:
        res.append([i[0],i[1],1])
    elif v1==v2:
        res.append([i[0],i[1],0])
    else:
        res.append([i[0],i[1],-1])

pd.DataFrame(res,columns=['ID','ID','对比']).to_csv(path2,index=0)


测试数据给下


代码如下:

import pandas as pd

input_file = "01.xlsx"
output_file = "output.xlsx"

df = pd.read_excel(input_file)
print(df)

_dict = dict(zip(df['ID'],df['Score']))

print(_dict)

_ids = [ x for x in _dict.keys() ]

result = {}
for _id, score in _dict.items():
    if _id not in result:
        result[_id] = {}
    for other_id in _ids:
        if _id == other_id:
            continue
        other_score = _dict[other_id]
        if score > other_score:
            value = 1
        elif score == other_score:
            value = 0
        else:
            value = -1
        result[_id][other_id] = value
print(result)

df = pd.concat({k: pd.Series(v) for k, v in result.items()}).reset_index()
df.columns = ['ID', 'ID','对比']
print(df)

df.to_excel(output_file, index=False)

输入: 01.xlsx

IDScore
12
22
32
42
53
63
75
85
94

输出为: output.xlsx

IDID对比
120
130
140
15-1
16-1
17-1
18-1
19-1
210
230
240
25-1
26-1
27-1
28-1
29-1
310
320
340
35-1
36-1
37-1
38-1
39-1
410
420
430
45-1
46-1
47-1
48-1
49-1
511
521
531
541
560
57-1
58-1
59-1
611
621
631
641
650
67-1
68-1
69-1
711
721
731
741
751
761
780
791
811
821
831
841
851
861
870
891
911
921
931
941
951
961
97-1
98-1

如有问题及时沟通

lst_score = []
if int(row[0]) > int(row[1]):
    lst_score.append(1)
elif int(row[0]) == int(row[1]):
    lst_score.append(0)
else:
    lst_score.append(-1)

具体代码得看你是啥格式的文件?

不好意思,刚才误解了,试试这个:

12的分数对比结果是:0
13的分数对比结果是:0
14的分数对比结果是:0
15的分数对比结果是:-1
16的分数对比结果是:-1
17的分数对比结果是:-1
18的分数对比结果是:-1
19的分数对比结果是:-1
23的分数对比结果是:0
24的分数对比结果是:0
25的分数对比结果是:-1
26的分数对比结果是:-1
27的分数对比结果是:-1
28的分数对比结果是:-1
29的分数对比结果是:-1
34的分数对比结果是:0
35的分数对比结果是:-1
36的分数对比结果是:-1
37的分数对比结果是:-1
38的分数对比结果是:-1
39的分数对比结果是:-1
45的分数对比结果是:-1
46的分数对比结果是:-1
47的分数对比结果是:-1
48的分数对比结果是:-1
49的分数对比结果是:-1
56的分数对比结果是:0
57的分数对比结果是:-1
58的分数对比结果是:-1
59的分数对比结果是:-1
67的分数对比结果是:-1
68的分数对比结果是:-1
69的分数对比结果是:-1
78的分数对比结果是:0
79的分数对比结果是:1

代码如下:

from itertools import combinations
id = [1,2,3,4,5,6,7,8,9]
score = [2,2,2,2,3,3,5,5,4]
d = dict(zip(id,score))
combo = combinations(id,2)
result = {i:-1 if d[i[0]]-d[i[1]]<0 else 1*bool(d[i[0]]-d[i[1]]) for i in combo}
for i, j in result.items():
    print(f'{i[0]}{i[1]}的分数对比结果是:{j}')

这个问题还和数据给出的方式相关,其实保证原始数据是一个简单的列表(同时包含ID和对应Score),或者说对应2个列表(同序的ID和对应的值),无非就是2层循环的处理,因为要排除同序号比较的(这里就是和后面的比较),所以简单处理一下即可,例如
(以ID和score分开列表为例):

IDList=[1,2,3,4,5,6,7,8,9]
ScoreList =[2,2,2,2,3,3,5,5,4]
# 接收结果的数组变量为RTList
RTList =[]
aLen = len(IDList)
for  i in  range( aLen  ):
    for  j in range(i+1, aLen) :
            RTList.append([IDList[i], IDList[j], ScoreList[i]-ScoreList[j] ])
print(RTList)

(以ID和score在一起的列表为例):

DataList=[ [1,2],[2,2],[3,2],[4,2],[5,3],[6,3],[7,5],[8,5],[9,4]]
# 接收结果的数组变量为RTList
RTList =[]
aLen = len(DataList)
for  i in  range( aLen  ):
    for  j in range(i+1, aLen) :
         RTList.append([DataList[i][0], DataList[j][0],DataList[i][1]-DataList[j][1] ])
print(RTList)

如果是要和其它的所有ID对应值比较,则稍微调整一下,把j的范围扩大为range(aLen),然后加一个if过滤掉i==j的情况即可,类似:

# 其余不变
for  i in  range( aLen  ):
    for  j in range( aLen) :
        if ( i != j ):
            RTList.append([DataList[i][0], DataList[j][0],DataList[i][1]-DataList[j][1] ])
# 其余不变

至于只记录1,0,-1这样的情况,其实可以稍微处理一下,比如定义一个函数:

def getS(in1, in2):
    if in1> in2:
        return 1
    if in1 == in2:
        return 0
    if in1 < in2:
        return -1

把其中的 DataList[i][1]-DataList[j][1] 转换为 getS(DataList[i][1], DataList[j][1] )

把其中的 ScoreList[i]-ScoreList[j] 转换为 getS( ScoreList[i], ScoreList[j] )

即可。

改下两个路径就行了


import pandas as pd
path1='D:/a.csv'   ###你的数据路径
path2='D:/b.csv'   ###你要报存的数据路径


df1=pd.read_csv(path1)
df1.index=df1.ID
rs=[]
for i in df1.index[0:-1]:
    for j in df1.index[1:]:
        if i<j:
            if df1.loc[i,'Score']>df1.loc[j,'Score']:
                r=[i,j,1]
            elif df1.loc[i,'Score']==df1.loc[j,'Score']:
                r=[i,j,0]
            else:
                r=[i,j,-1]
            rs.append(r)

df2=pd.DataFrame(rs,columns=['ID1','ID2','对比'])
df2.to_csv(path2,index=0)

img


```python
import pandas as pd
#前面读取文件可以pd.read_excel()
#pd.read_excel()
ids=[1,2,3,4,5,6,7,8,9]
score=[2,2,2,2,3,3,5,5,4]
datas=pd.DataFrame({'ids':ids,'score':score})
dat=pd.DataFrame(columns=['nid','ids','score'])
for i,j in zip(ids,score):
    datas['nid']=i
    datas['scores']=j
    dat=dat.append(datas)
#这里筛选出第一个id小于第二个id,如果只是要不等的话改成dat=dat.loc[dat.nid!=dat.ids,:]就可以
dat=dat.loc[dat.nid<dat.ids,:]
dat['compare']=dat['scores']-dat['score']
dat['compare']=dat['compare'].apply(lambda x:1 if x>0  else (-1 if x<0 else 0))
dat[['nid','ids','compare']]
#输出可以选择本地路径
#dat.to_csv('path',index=None)

我想你的目的是高效

import pandas as pd

a=pd.DataFrame({"id":[i for i in range(10)],"score":[i for i in range(10)]})
b=a.copy()
a["dkl"]=1
b["dkl"]=1
c=pd.merge(a,b,on="dkl")
c["对比"]=0
c["对比"][c["score_x"]>c["score_y"]]=1
c["对比"][c["score_x"]<c["score_y"]]=-1
print(c[["id_x","id_y","对比"]])
if __name__ == '__main__':
    pass