Вам необходимо сначала отсортировать столбцы по sort_values
, а затем groupby
с пользовательской функцией с numpy.split
и вернуть длину каждой группы в новую строку нового DataFrame:
Идея от идеального Ответ MaxU , спасибо.
Используйте для top 30-30-30
:
user = user.sort_values(['User','Count'], ascending=[True, False])
def f(x):
#split to 4 groups, because 3 + 3 + 3 != 1
a, b, c, d = np.split(x, [int(.3*len(x)), int(.6*len(x)), int(.9*len(x))])
return pd.Series([len(a), len(b), len(c)], index=['30','30','30'])
df = user.groupby('User').apply(f)
df['sum'] = df.sum(axis=1)
print (df)
30 30 30 sum
User
101 1 2 1 4
102 2 2 2 6
и для 30-30-40
:
user = user.sort_values(['User','Count'], ascending=[True, False])
def f(x):
#split to 3 groups, because 3 + 3 + 4 == 1
a, b, c = np.split(x, [int(.3*len(x)), int(.6*len(x))])
return pd.Series([len(a), len(b), len(c)], index=['30','30','40'])
df = user.groupby('User').apply(f)
df['sum'] = df.sum(axis=1)
print (df)
30 30 40 sum
User
101 1 2 2 5
102 2 2 3 7
EDIT:
Группы должны быть созданы list comprehension
:
def f(x):
a, b, c = np.split(x.index, [int(.3*len(x)), int(.6*len(x))])
L = [a,b,c]
return [i for i, y in zip(range(len(L),0,-1) ,L) for j in y]
user['Groups'] = user.groupby('User')['User'].transform(f)
print (user)
User Country Count Groups
0 101 India 85 3
1 101 Japan 78 2
2 101 India 70 2
6 101 Austria 60 1
5 101 UK 8 1
7 102 Japan 30 3
4 102 Japan 6 3
9 102 UK 6 2
3 102 Brazil 5 2
8 102 Singapore 5 1
10 102 UK 5 1
11 102 UK 4 1