How to access two elements at once in a for loop without duplicates in python?

Viewed 65

I have a table that looks like this:

Celebrity Username
A user1
B user1
C user2
A user3
A user2
D user2
D user3

I wrote a function to find the overlaps of users between two celebrities:

def num_of_fans_overlap(cel1,cel2,data,Celebrity,Usernames):
    l = [cel1,cel2]
    Res = len(data.loc[data['Usernames'].map(data.groupby('Usernames').agg(set)['Celebrity'].eq(set(l)))])/2
    return print(int(Res))

for example, if I run num_of_fans_overlap(A,B,data,"Celebrity","Username"), I will get 1, which means one user has followed both celebrities.

Now I want to run a for loop, and the output should look like this:

("A", "B", 1)
("A", "C", 1)
("A", "D", 2)
("B", "C", 0)
("B", "D", 0)
("C", "D", 1)

I have been stuck here. Hope someone can help.
3 Answers

Check with crosstab then dot

s = pd.crosstab(df.Celebrity,df.Username)
s = s.dot(s.T)
out = s.mask(np.triu(np.ones(s.shape)).astype(bool)).stack()
Out[301]: 
Celebrity  Celebrity
B          A            1.0
C          A            1.0
           B            0.0
D          A            2.0
           B            0.0
           C            1.0
dtype: float64

First, the function num_of_fans_overlap shouldn't return a print().

def num_of_fans_overlap(cel1,cel2,data):
    l = [cel1,cel2]
    Res = len(data.loc[data['Usernames'].map(data.groupby('Usernames').agg(set)['Celebrity'].eq(set(l)))])/2
    return int(Res)

Second, if the variable celebrities is a list of unique values on the Celebrity column.


from itertools import combinations
celebrities = list(data.Celebrity.unique())
for (cel1, cel2) in combinations(celebrities, 2):
   fans_overlap = num_of_fans_overlap(cel1, cel2, data)
   print((cel1, cel2, fans_overlap))

The naive way to do this:

celebs = ["A", "B", "C", "D"]
for i in range(len(celebs)):
    for j in range(i+1, len(celebs)):
        celeb_pairs = (celebs[i], celebs[j])
        run_your_function_here(*celeb_pairs, other, parameters)

You can also do this elegantly by using the itertools.combinations function:

import itertools

celebs = ["A", "B", "C", "D"]
for celeb1, celeb2 in itertools.combinations(celebs, 2):
    run_your_function_here
Related