Python中每个用户的排名

问题描述 投票:1回答:1

我有一大堆来自移动用户的博客,我需要创建一个名为'hop'的新列。

因此,在下面,用户47294872934从印度(0小时)到英国(15小时)。因此,他们的第一个位置是印度,第二个位置是英国。

所以,我想要一个像这样的新专栏,

                      hour   hop
userid      country       
47294872934 India        0   1
            UK          15   2
82718927392 Portugal     4   3
            Spain        2   2
            UK           0   1

在上文中,每个用户具有多个跳。用户82718927392在一天中从英国(1)到西班牙(2)到葡萄牙(3)。这是一天,所以小时越高,旅行越晚。

我已经尝试过排名(下面)来做这件事,但它在整个数据集中排名,而不是单个用户。我也希望排名是一个int而不是一个浮点数。

任何帮助都会很棒!

In [12]: df2
Out[12]: 
                      hour
userid      country       
47294872934 India        0
            UK          15
82718927392 Portugal     4
            Spain        2
            UK           0

In [13]: df2.rank(ascending=True)
Out[13]: 
                      hour
userid      country       
47294872934 India      1.5
            UK         5.0
82718927392 Portugal   4.0
            Spain      3.0
            UK         1.5

包括例子

    In [32]: df2 = df.groupby(['userid', 'country'])[['hour']].min().groupby(level=0).cumcount()+1

In [33]: df2['hop'] = df2.sort_values('hour').groupby(level=0).cumcount()+1
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-34-27bb4b4b86fa> in <module>()
----> 1 df2['hop'] = df2.sort_values('hour').groupby(level=0).cumcount()+1

~/anaconda3/lib/python3.7/site-packages/pandas/core/series.py in sort_values(self, axis, ascending, inplace, kind, na_position)
   2444         """
   2445         inplace = validate_bool_kwarg(inplace, 'inplace')
-> 2446         axis = self._get_axis_number(axis)
   2447 
   2448         # GH 5856/5853

~/anaconda3/lib/python3.7/site-packages/pandas/core/generic.py in _get_axis_number(self, axis)
    373                 pass
    374         raise ValueError('No axis named {0} for object type {1}'
--> 375                          .format(axis, type(self)))
    376 
    377     def _get_axis_name(self, axis):

ValueError: No axis named hour for object type <class 'pandas.core.series.Series'>

进一步测试

    ...: df['hop'] = df.groupby(level=0).hour.rank(method='dense').astype(int)

In [36]: df
Out[36]: 
         userid   country      date  hour  hop
0   82718927392        UK  20101025     0    1
1   82718927392        UK  20101025     1    1
2   82718927392        UK  20101025     1    1
3   82718927392        UK  20101025     1    1
4   82718927392     Spain  20101025     2    1
5   82718927392     Spain  20101025     2    1
6   82718927392     Spain  20101025     2    1
7   82718927392     Spain  20101025     3    1
8   82718927392  Portugal  20101025     4    1
9   82718927392  Portugal  20101025     5    1
10  47294872934     India  20101025     0    1
11  47294872934     India  20101025     0    1
12  47294872934     India  20101025     1    1
13  47294872934        UK  20101025    15    1
14  47294872934        UK  20101025    17    1
15  47294872934        UK  20101025    19    1
python python-3.x pandas pandas-groupby
1个回答
1
投票

由于您需要每个userid中的计数器,因此您需要首先对该列进行分组。

sort_values + groupby + cumcount

df['hop'] = df.sort_values('hour').groupby(level=0).cumcount()+1

                      hour  hop
userid      country            
47294872934 India        0    1
            UK          15    2
82718927392 Portugal     4    3
            Spain        2    2
            UK           0    1

groupby + rank

df['hop'] = df.groupby(level=0).hour.rank(method='dense').astype(int)

                      hour  hop
userid      country            
47294872934 India        0    1
            UK          15    2
82718927392 Portugal     4    3
            Spain        2    2
            UK           0    1

如果用户在同一时间有多个国家/地区,cumcount将增加计数,而rank则不会。

© www.soinside.com 2019 - 2024. All rights reserved.