Python中每个用户的排名

时间:2018-10-29 13:51:47

标签: python python-3.x pandas pandas-groupby

我有来自移动用户的大量博客,我需要创建一个名为“ 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)旅行。这是一天,所以小时数越高,旅行发生的时间就越晚。

我已经尝试过在下面进行排名,但是它在整个数据集中排名,而不是单个用户。我还希望等级为整数而不是浮点数。

任何帮助都会很棒!

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

1 个答案:

答案 0 :(得分: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不会。