0

I have 3 lists with similar float values in a1, a2, a3 (whose lengths are equal).

for i in length(a1,a2,a3):
  Find the increasing / decreasing order of a1[i], a2[i], a3[i]
  Rank the values based on the order 

Is there a simple/efficient way to do this? Rather than writing blocks of if-else statements?

I am trying to calculate the Friedman test ranks in Python. Though there is a scipy.stats.friedmanchisquare function, it doesn't return the ranks The Friedman test

EDIT

I have data like this in the Image 1.

  • a1 has week 1
  • a2 has week 2 and
  • a3 has week 3 I want to rank the values like in this Image 2

I tried comparing the values by using if else loops like this

for i in range(0,10):
if(acc1[i]>acc2[i]):
    if(acc1[i]>acc3[i]):
        rank1[i] = 1
        if(acc2[i]>acc3[i]):
            rank2[i] = 2
            rank3[i] = 3
mmm
  • 23
  • 6
  • What do you mean by "rank" here? What kind of output do you want? – Błotosmętek Jun 14 '17 at 14:06
  • Please elaborate. Your question seems to vague and also do post what you have tried and specific problem with the code you have written. – amrx Jun 14 '17 at 14:07
  • @Błotosmętek I want to compare the values in the same index of the 3 lists and rank them in increasing order. please refer to this video if you've further questions about rank https://www.youtube.com/watch?v=KbBn4A7VFMs – mmm Jun 14 '17 at 14:28
  • @amrx Added part of the code I have written so far. – mmm Jun 14 '17 at 14:29

2 Answers2

0

friedmanchisquare uses scipy.stats.rankdata. Here's one way you could use rankdata with your three lists. It creates a list called ranks, where ranks[i] is an array containing the ranking of [a1[i], a2[i], a3[i]].

In [41]: a1
Out[41]: [1.0, 2.4, 5.0, 6]

In [42]: a2
Out[42]: [9.0, 5.0, 4, 5.0]

In [43]: a3
Out[43]: [5.0, 6.0, 7.0, 2.0]

In [44]: from scipy.stats import rankdata

In [45]: ranks = [rankdata(row) for row in zip(a1, a2, a3)]

In [46]: ranks
Out[46]: 
[array([ 1.,  3.,  2.]),
 array([ 1.,  2.,  3.]),
 array([ 2.,  1.,  3.]),
 array([ 3.,  2.,  1.])]

If you convert that to a single numpy array, you can then easily work with either the rows or columns of ranks:

In [47]: ranks = np.array(ranks)

In [48]: ranks
Out[48]: 
array([[ 1.,  3.,  2.],
       [ 1.,  2.,  3.],
       [ 2.,  1.,  3.],
       [ 3.,  2.,  1.]])

In [49]: ranks.sum(axis=0)
Out[49]: array([ 7.,  8.,  9.])
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
0

You could define a simple function that returns the order of the sorts:

def sort3(a,b,c):
    if (a >= b):
        if (b >= c):
            return (1, 2, 3)
        elif (a >= c):
            return (1, 3, 2)
        else:
            return (3, 1, 2)
    elif (b >= c):
        if (c >= a):
            return (2, 3, 1)
        else:
            return (2, 1, 3)
    else:
        return (3, 2, 1)

Or consider using this https://stackoverflow.com/a/3382369/3224664

def argsort(seq):
    # http://stackoverflow.com/questions/3071415/efficient-method-to-calculate-the-rank-vector-of-a-list-in-python
    return sorted(range(len(seq)), key=seq.__getitem__)
a = [1,3,5,7]
b = [2,2,2,6]
c = [3,1,4,8]
for i in range(len(a)):
    print(argsort([a[i],b[i],c[i]]))
ginginsha
  • 142
  • 1
  • 11
  • i wanted to write the function like the first one you wrote but was wondering if it could be done in a more efficient/quick way like your second function or the previous answer. thanks – mmm Jun 14 '17 at 14:48