Python 熊猫的排名基于多个列
我有以下数据帧:Python 熊猫的排名基于多个列,python,python-3.x,pandas,Python,Python 3.x,Pandas,我有以下数据帧: event_id occurred_at user_id 19148 2015-10-01 1 19693 2015-10-05 2 20589 2015-10-12 1 20996 2015-10-15 1 20998 2015-10-15 1 23301 2015-10-23 2 23630 2015-10-26
event_id occurred_at user_id
19148 2015-10-01 1
19693 2015-10-05 2
20589 2015-10-12 1
20996 2015-10-15 1
20998 2015-10-15 1
23301 2015-10-23 2
23630 2015-10-26 1
25172 2015-11-03 1
31699 2015-12-11 1
32186 2015-12-14 2
43426 2016-01-13 1
68300 2016-04-04 2
71926 2016-04-19 1
我想为每个用户按时间顺序(1到n)对事件进行排序
我可以通过以下方式实现这一目标:
df.groupby('user_id')['occurred_at'].rank(method='dense')
但是,对于发生在同一日期(对于同一用户)的那两行,我的排名是相同的:
20996 2015-10-15 1
20998 2015-10-15 1
如果事件日期相同,我希望比较事件id
,并任意将事件与最低的事件id
排序。我怎样才能轻松做到这一点
我可以对排名进行后期处理,以确保每个排名只使用一次,但这似乎相当庞大
编辑:如何复制:
复制粘贴data.csv
文件中的数据。
然后:
将熊猫作为pd导入
df=pd.read\u csv('data.csv',delim\u whitespace=True)
df['rank']=df.groupby('user_id')['发生在'].rank(method='dense')
>>>df[df['user_id']==1]
事件\u id发生在\u用户\u id级别
0 19148 2015-10-01 1 1.0
2 20589 2015-10-12 1 2.0
3 20996 2015-10-15 1 3.0在分组前对值(“事件id”)进行排序
,然后将方法class='first'
传递到等级
还请注意,如果在
发生的尚未是
日期时间,请将其设置为日期时间
完整可验证代码的参考
我不能复制这个:
01.011.022.033.043.052.064.075.086.093.0107.0114.0128.0
它适用于meHmm,我认为这是一个bug,它不应该这样做,我现在可以复制这个我理解你的问题,你能在上面发布一个看起来像bug的问题吗,rank
方法未正确处理字符串,如果您将日期列转换为datetime
dtype
,则如果您看到下面的答案,它将正常工作。此外,如果您通过method='first',则会出现一个
AttributeError`我会将此作为一个问题发布,因为它应该起作用。这是什么版本?由于0.18.1
上的ValueError
失败,我得到了AttributeError:“SeriesGroupBy”对象没有属性“\u aggregate\u item\u by\u item”
出于某种原因,我的numpy版本是1.11.0
python 64位3.4.3。5@EdChum我马上去查numpy。我添加了完整的代码片段供您测试。@EdChumnp.\uuuuu版本\uuuuuu
也是1.11.0
是的,问题是如果日期列仍然是字符串,那么转换为datetime
会失败,所以我认为这是一个错误
import pandas as pd
df = pd.read_csv('data.csv', delim_whitespace=True)
df['rank'] = df.groupby('user_id')['occurred_at'].rank(method='dense')
>>> df[df['user_id'] == 1]
event_id occurred_at user_id rank
0 19148 2015-10-01 1 1.0
2 20589 2015-10-12 1 2.0
3 20996 2015-10-15 1 3.0 <--
4 20998 2015-10-15 1 3.0 <--
6 23630 2015-10-26 1 4.0
7 25172 2015-11-03 1 5.0
8 31699 2015-12-11 1 6.0
10 43426 2016-01-13 1 7.0
12 71926 2016-04-19 1 8.0
# unnecessary if already datetime, but doesn't hurt to do it anyway
df.occurred_at = pd.to_datetime(df.occurred_at)
df['rank'] = df.sort_values('event_id') \
.groupby('user_id').occurred_at \
.rank(method='first')
df
from StringIO import StringIO
import pandas as pd
text = """event_id occurred_at user_id
19148 2015-10-01 1
19693 2015-10-05 2
20589 2015-10-12 1
20996 2015-10-15 1
20998 2015-10-15 1
23301 2015-10-23 2
23630 2015-10-26 1
25172 2015-11-03 1
31699 2015-12-11 1
32186 2015-12-14 2
43426 2016-01-13 1
68300 2016-04-04 2
71926 2016-04-19 1"""
df = pd.read_csv(StringIO(text), delim_whitespace=True)
df.occurred_at = pd.to_datetime(df.occurred_at)
df['rank'] = df.sort_values('event_id').groupby('user_id').occurred_at.rank(method='first')
df