将观测日期重新堆叠并转换为序列号?

时间:2017-04-04 04:11:43

标签: 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      R2      R3
1       37.2    68.9    NaN
2       45.1    42.9    NaN
3       56      39      42.9

我玩过pd.pivot和pd.unstack,但无法得到我需要的东西。

建议?

2 个答案:

答案 0 :(得分:0)

  • 首先按USERDATE排序值(这似乎已在示例数据中完成,但只是为了确定)。
  • 然后创建一个新列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')
     )

答案 1 :(得分: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