Python:是否有一种只计算日期的解决方案(pivot或groupby)

2024-05-16 04:21:34 发布

您现在位置:Python中文网/ 问答频道 /正文

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

import pandas as pd
from datetime import date

d1 = date(2020,11,23)
d2 = date(2020,11,24)
d3 = date(2020,11,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
------------------------------------

Tags: testimport信息dfdatearea解决方案d2
2条回答

我使用了其他方法,而不是枢轴-

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()方法提供唯一值和它们出现的次数。 在这之后,我对日期有了问题,我有两列“里程碑1”和“里程碑2”,其中混合了日期,字符串包含“-”表示空日期。 我在这里做的是将空日期转换为np.nan,因此当我对其使用方法时,它不会计算空日期(“-”)。 最后,我将df按“Area”列分组,计算每列具有值的时间,并将其分配给新的数据帧

结果:

    Sum_of_Sub_Area     Sum_of_Milestone_2
Area_A  2               1
Area_B  1               0

希望有帮助

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

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

d1 = date(2020,11,23)
d2 = date(2020,11,24)
d3 = date(2020,11,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

相关问题 更多 >