2017-04-04 48 views
2

我有一排CSV每单个每个观察:将观察日期拆分并将日期转换为序列号?

USER DATE SCORE 
1 7/9/2015 37.2 
1 11/18/2015 68.9 
2 7/7/2015 45.1 
2 11/2/2015 42.9 
3 6/4/2015 56 
3 10/27/2015 39 
3 5/11/2016 42.9 

我想生产,其中第一观察被分配到第一回合,第二到第二轮,以此类推一个数据帧。所以,结果会是什么样子:

USER R1  R2  R3 
1  37.2 68.9 NaN 
2  45.1 42.9 NaN 
3  56  39  42.9 

我已经pd.pivot和pd.unstack玩耍了,但不能得到我所需要的。

对此提出建议?通过USERDATE

回答

0

您可以使用groupbyapply创建新列:

#if necessary sort values 
df = df.sort_values(by=['USER','DATE']) 

df = df.groupby('USER')['SCORE'].apply(lambda x: pd.Series(x.values)) 
     .unstack() 
     .rename(columns = lambda x: 'R' + str(x+1)) 
     .reset_index() 
print (df) 
    USER R1 R2 R3 
0  1 37.2 68.9 NaN 
1  2 45.1 42.9 NaN 
2  3 56.0 39.0 42.9 

pivotunstack另一种解决方案:

#if necessary sort values 
df = df.sort_values(by=['USER','DATE']) 

df = pd.pivot(index=df['USER'],columns=df.groupby('USER').cumcount() + 1,values=df['SCORE']) 
     .add_prefix('R') 
     .reset_index() 
print (df) 
    USER R1 R2 R3 
0  1 37.2 68.9 NaN 
1  2 45.1 42.9 NaN 
2  3 56.0 39.0 42.9 
0
  • 首先排序值(这似乎是在例如数据已经完成,但只是要确定)。
  • 然后创建一个新列ROUND,它将按顺序为每个用户编号条目。
  • 将索引设置为列USERROUND
  • 最后,拆除SCORE列。

下面是一些示例代码:

import pandas as pd 
from io import StringIO 

data = '''USER DATE SCORE 
1 7/9/2015 37.2 
1 11/18/2015 68.9 
2 7/7/2015 45.1 
2 11/2/2015 42.9 
3 6/4/2015 56 
3 10/27/2015 39 
3 5/11/2016 42.9''' 
df = (pd.read_csv(StringIO(data),sep='\s+',parse_dates=['DATE']) 
     .sort_values(by=['USER','DATE']) 
     .assign(ROUND = lambda x: x.groupby('USER').cumcount() + 1) 
     .set_index(['USER','ROUND'])['SCORE'] 
     .unstack() 
     .add_prefix('R') 
    )