Python 取消堆叠并将观测日期转换为序列号?

Python 取消堆叠并将观测日期转换为序列号?,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个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

我有一个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,但无法得到我需要的

建议?

  • 首先按
    用户
    日期
    对值进行排序(这似乎已经在示例数据中完成了,但只是为了确定)
  • 然后创建一个新列
    ROUND
    ,该列将按顺序为每个用户的条目编号
  • 将索引设置为列
    USER
    ROUND
  • 最后,取消堆叠
    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')
     )

您可以使用
groupby
apply
来创建新列:

#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
另一个解决方案包括和:

#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