Python:是否有一种解决方案数据透视表或groupby仅计算日期

问题描述

是否有一种简单的解决方案来获取以下信息?我是python和DataFrames的新手,目前无法解决此问题。

import pandas as pd
from datetime import date

d1 = date(2020,11,23)
d2 = date(2020,24)
d3 = date(2020,25)

df_test = pd.DataFrame({'Area': ['Area_A','Area_A','Area_B'],'Sub_Area': ['Area_A1','Area_A2','Area_B1'],'Milestone_1': [d1,d2,'-'],'Milestone_2': [d3,'-','-']}) 
df_test 
------------------------------------
     Area Sub_Area Milestone_1 Milestone_2
0  Area_A  Area_A1  2020-11-23  2020-11-25
1  Area_A  Area_A2  2020-11-24           -
2  Area_B  Area_B1           -           -
------------------------------------

我需要为每个区域估计此信息的最新里程碑:

  1. 子区域的数量
  2. 每个分区的最近里程碑和
  3. 每个区域最近的里程碑数量

最终表或数据框应如下所示:

------------------------------------
     Area  Sum_of_Sub_Area Sum_of_Milestone_1 Sum_Milestone_2
0  Area_A  2               2                  1
1  Area_B  1               0                  0
------------------------------------

有人可以帮我吗?

我第一次尝试使用pivot_table并没有提供正确的解决方案,因为我只需要计算日期Area_B在任何Milestone中没有日期:

df_test.pivot_table(values=['Sub_Area','Milestone_1','Milestone_2'],index=['Area'],aggfunc=['count'],fill_value=0)

------------------------------------
             count
       Milestone_1 Milestone_2 Sub_Area
Area
Area_A           2           2        2
Area_B           1           1        1
------------------------------------

解决方法

这全是关于进入agg()的数据的一致性

  1. -替换为np.nan,然后确保里程碑列仍为datetime64
  2. 具有 count 的简单groupby()agg()得到您想要的
from datetime import date

d1 = date(2020,11,23)
d2 = date(2020,24)
d3 = date(2020,25)

df_test = pd.DataFrame({'Area': ['Area_A','Area_A','Area_B'],'Sub_Area': ['Area_A1','Area_A2','Area_B1'],'Milestone_1': [d1,d2,'-'],'Milestone_2': [d3,'-','-']}) 

dfc = df_test.replace({"-":np.nan}).astype({c:"datetime64" for c in df_test.columns if "Mile" in c})\
    .groupby("Area").agg({"Milestone_1":"count","Milestone_2":"count"})

print(dfc.to_string())

输出

        Milestone_1  Milestone_2
Area                            
Area_A            2            1
Area_B            0            0
,

我使用了除数据透视以外的其他方法-

areas = df_test["Area"].unique().tolist()
est_by_area = pd.DataFrame(index = areas)
est_by_area["Sum_of_Sub_Area"] = df_test["Area"].value_counts().to_frame()
df_test[["Milestone_1","Milestone_2"]] = df_test[["Milestone_1","Milestone_2"]].replace("-",np.nan)
est_by_area["Sum_of_Milestone_1"] = df_test.groupby("Area")["Milestone_1"].count().to_frame()
est_by_area["Sum_of_Milestone_2"] = df_test.groupby("Area")["Milestone_2"].count().to_frame()

我将回顾我在这里所做的事情:

首先,我创建了这些区域的唯一列表。 我创建了一个名为“ est_by_area”的新数据框,而其索引是我之前创建的区域列表。 之后,我将value_counts()方法分配给“ Sum_of_Sub_Area”列,value_counts()方法为您提供唯一的值和它们出现的次数。 之后,我遇到了日期问题,我有2个列“ Milestone_1”和“ Milestone_2”,其中包含混合日期,字符串包含“-”表示空日期。 我在这里所做的是将空日期转换为np.nan,因此当我在其上使用方法时,它将不计算空日期(“-”)。 最后,我按“面积”(Area)列对df分组,并计算每列包含值的次数,并将其分配给新数据框。

结果:

    Sum_of_Sub_Area     Sum_of_Milestone_2
Area_A  2               1
Area_B  1               0

希望有帮助。