【问题标题】:pandas pivot to calculate difference between max date and second to max datepandas pivot 计算最大日期和秒到最大日期之间的差异
【发布时间】:2020-11-12 11:40:14
【问题描述】:

我有一种情况,我需要对数据进行透视,以便在日期字段的基础上获取最近的和最近的条目。我的数据框如下所示:

State   country      Date             confirmed deaths  recover
  A         C     1/22/20             1         0       0
  A         C     1/23/20             1         0       0
  A         C     1/24/20             15        0       0
  A         C     1/25/20             39        0       0
  B         C     1/26/20             60        0       0
  B         C     1/27/20             70        0       0
  B         C     1/28/20            106        0       0
  B         C     1/29/20            152        2       0
  B         C     1/30/20            200        2       0

我想要的输出应该是这样的: 因此,新的列已确认,死亡和恢复应该根据 Max(Date) 获取值,该值是状态 A 的 1/25/20 和状态 B 的 1/30/20 和 newcases , newdeaths , newrecover 应该是最大日期值的差 - 秒到最大日期值。

For example for state A new cases = 39-15= 24, newdeaths = 0-0=0 , newrecover = 0-0=0

39 例在最大日期,24 例在最大日期的第二个,因为我需要获得每日更改。这应该是动态的,因为它需要每天获取

State   country   confirmed deaths  recover      newcases     newdeaths    newrecover
  A        C           39       0        0       24           0             0
  B        C           200      2        0       48           2             0

【问题讨论】:

  • 对于 B 列 B,newdeaths 是否应该为 0,因为 2-2=0

标签: python-3.x pandas pivot pivot-table aggregate


【解决方案1】:

sort_values 按日期升序和groupby 日期并提取每个组中的最后一个值。加入另一个 groupby 日期,从每个组中的最后一个值中减去第二个最后一个值。

链式解决方案

 df.groupby('State').tail(1).drop(columns=['Date']).merge(df.sort_values(by='Date', ascending=True).groupby('State')\
[['confirmed', 'deaths', 'recover']].apply(lambda s:(s.iloc[-1].sub(s.iloc[-2])))\
    .reset_index().rename(columns={'confirmed':'newcases','deaths':\
            'newdeaths','recover':'newrecover'}), how='left', on='State')

分步解决方案

g=df.groupby('State').tail(1).drop(columns=['Date'])

g1=df.sort_values(by='Date', ascending=True).groupby('State')\
[['confirmed', 'deaths', 'recover']].apply(lambda s:(s.iloc[-1].sub(s.iloc[-2])))\
    .reset_index().rename(columns={'confirmed':'newcases','deaths':\
            'newdeaths','recover':'newrecover'})


newdf=g.merge(g1, how='left', on='State')


   State country  confirmed  deaths  recover  newcases  newdeaths  newrecover
0     A       C         39       0        0        24          0           0
1     B       C        200       2        0        48          0           0 

   newrecover  
0           0  
1           0  

【讨论】:

  • 我不需要我在输出中提到的日期列。如何摆脱它?输出应该像我上面显示的那样聚合。
  • 更快的解决方案@Django0602
【解决方案2】:

一种方法是使用idxmax 创建一个掩码m,以返回date 的一系列最大索引。然后,您可以创建一个 groupby 对象 gb 作为过滤 m 的基础,方法是将其传递给 .loc(包含每个组的最大日期的行)并使用 .appendm-1(包含每组第二高的日期)。然后,此 groupby 对象库可以与相关列上的 .diff() 一起使用(例如 df['new cases'] = gb['confirmed'].diff())。

m = df.reset_index().groupby(['State', 'country'])['index'].idxmax()
gb = df.loc[m].append(df.loc[m-1]).sort_index().groupby('State')
df['newcases'] = gb['confirmed'].diff()
df['newdeaths'] = gb['deaths'].diff()
df['newrecover'] = gb['recover'].diff()
df = df.dropna().drop('Date', axis=1)
df

输出:

    State   country     confirmed   deaths  recover newcases    newdeaths   newrecover
3   A       C           39          0       0       24.0        0.0         0.0
8   B       C           200         2       0       48.0        0.0         0.0

【讨论】:

  • 我不需要我在输出中提到的日期列。如何摆脱它?
  • @Django0602 查看修改后的答案。您可以删除带有.drop('Date', axis=1) 的列,因此倒数第二行的完整代码现在是df = df.dropna().drop('Date', axis=1)
  • TypeError: diff() got an unexpected keyword argument 'axis' ,我收到此错误
  • 我刚刚运行了上面的代码,它运行良好。您是否将.drop('Date', axis=1) 粘贴到某处?
  • 是的,我做到了。在您提到的同一地点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-17
相关资源
最近更新 更多