2017-06-23 86 views
1

我有这样的数据帧:排名在多个列熊猫

dict_data = {'id' : [1,1,1,2,2,2,2,2], 
'datetime' : np.array(['2016-01-03T16:05:52.000000000', '2016-01-03T16:05:52.000000000', 
     '2016-01-03T16:05:52.000000000', '2016-01-27T15:45:20.000000000', 
     '2016-01-27T15:45:20.000000000', '2016-11-27T15:08:04.000000000', 
     '2016-11-27T15:08:04.000000000', '2016-11-27T15:08:04.000000000'], dtype='datetime64[ns]')} 

df_data=pd.DataFrame(dict_data) 

的数据看起来像这样

Data

我想排名在客户ID和日期,我用这个代码

(df_data.assign(rn=df_data.sort_values(['datetime'], ascending=True) 
....:      .groupby(['datetime','id']) 
....:      .cumcount() + 1) 
....:  .sort_values(['datetime','rn']) 
....:) 

我通过每个日期的ID得到不同的等级:

table with rank

我想看到的是ID列,但对于同一日期时间获取每个ID同一职级。

+0

排名的详细信息的方法也许提供了一个实际的布局你想要的输出? :)不知道我完全得到它! – Roelant

+0

并添加进口熊猫作为PD,作为NP进口numpy也会有所帮助:) – Roelant

回答

0

这里是如何通过datetime和ID排名:

##### RANK BY datetime and id ##### 
In[]: df_data.rank(axis =0,ascending = 1, method = 'dense') 
Out[]: 
    datetime id 
0   1 1 
1   1 1 
2   1 1 
3   2 2 
4   2 2 
5   3 2 
6   3 2 
7   3 2 

##### GROUPBY id AND USE APPLY TO GET VALUE FOR FOR EACH GROUP ##### 
In[]: df_data.rank(axis =0,ascending = 1, method = 'dense').groupby('id').apply(lambda x: x) 
Out[]: 
    datetime id 
0   1 1 
1   1 1 
2   1 1 
3   2 2 
4   2 2 
5   3 2 
6   3 2 
7   3 2 

##### THEN RANK INSIDE EACH GROUP ##### 

In[]: df_data.assign(rank=df_data.rank(axis =0,ascending = 1, method = 'dense').groupby('id').apply(lambda x: x.rank(axis =0,ascending = 1, method = 'dense'))['datetime']) 
Out[]: 
      datetime id rank 
0 2016-01-03 16:05:52 1  1 
1 2016-01-03 16:05:52 1  1 
2 2016-01-03 16:05:52 1  1 
3 2016-01-27 15:45:20 2  1 
4 2016-01-27 15:45:20 2  1 
5 2016-11-27 15:08:04 2  2 
6 2016-11-27 15:08:04 2  2 
7 2016-11-27 15:08:04 2  2 

如果你想改变你的排名会得到来自pandas documentation on ranking

+0

Abhijay我想通过ID进行分区。因此,对于ID = 2,排名将从1开始。 – Nick

+0

@尼克在问题中没有明确提及。请编辑。我希望这是你想要的理想结果。 –

+0

@ Abhijay Ghildyal密集的排名似乎没有按预期工作。例如对于ID = 2所有日期= 2016-01-27 15:45:20应该有排名1和所有日期= 2016-11-27 15:08:04应该有排名= 2 – Nick