【问题标题】:Replace the missing months & year in date column using python使用python替换日期列中缺少的月份和年份
【发布时间】:2018-03-16 09:08:38
【问题描述】:

我有一个带有日期列的数据框,根据年份和月份缺少一些数据。我必须显示我的数据集中所有年份的月份,并且相应的列应该显示为零。

我的数据框是这样的

 Date    Churn    Churnrate  customerID
2008,01  726.0  0.542398        2763
2008,02  345.0  0.257751        1351
2012,11    NaN       NaN           6
2013,01    3.0  0.002241          24
2013,02   10.0  0.007471          34
2013,03   25.0  0.018678          73
2013,04   25.0  0.018678          75
2013,05   14.0  0.010459          61
2013,06   19.0  0.014195          69
2013,07   27.0  0.020172         103
2013,08   22.0  0.016436          79
2013,09   19.0  0.014195          70
2013,10   28.0  0.020919          83
2013,11   22.0  0.016436          78
2013,12   19.0  0.014195          75
2014,01   17.0  0.012701          63
2014,02   21.0  0.015689          55
2014,03    7.0  0.005230          66
2014,04   24.0  0.017931          86
2014,05   18.0  0.013448          90
2014,06   14.0  0.010459          50

例如在 2018 年,我只有两个月的记录,但我想在相应的列中显示所有 12 个月的 0

我的另一个数据框是这样的

Months  Retention_Rate  Customer_Count
0  2008/01        0.145916             133
1  2008/02        0.924663             762
2  2008/03        0.074544              67
3  2014/07        0.058684              45
4  2014/08        0.069786              61
5  2014/09        0.076130              64
6  2014/10        0.061856              60
7  2014/11        0.082474              69

我使用了下面给出的相同答案

predicted_retention_rate = predicted_retention_rate.set_index('Months')
idx =(pd.MultiIndex.from_product(predicted_retention_rate.index.str.split('/', expand=True).levels)
        .map('/'.join))

final_retention_rate_predicted = predicted_retention_rate.reindex(idx, fill_value=0).rename_axis('Months').reset_index()
print (final_retention_rate_predicted)

但此输出中缺少某些月份

Months  Retention_Rate  Customer_Count
0   2008/01        0.145916             133
1   2008/02        0.924663             762
2   2008/03        0.074544              67
3   2008/07        0.000000               0
4   2008/08        0.000000               0
5   2008/09        0.000000               0
6   2008/10        0.000000               0
7   2008/11        0.000000               0
8   2014/01        0.000000               0
9   2014/02        0.000000               0
10  2014/03        0.000000               0
11  2014/07        0.058684              45
12  2014/08        0.069786              61
13  2014/09        0.076130              64
14  2014/10        0.061856              60
15  2014/11        0.082474              69

查看上面的数据框,2008 年包含 01,02,03 但不包含 04,05,06 和 2014 年相同。我可以知道我哪里出错了。

【问题讨论】:

    标签: python pandas date replace


    【解决方案1】:

    我认为需要reindexsplit Date 创建的新reindexMultiIndexmapjoin

    df = df.set_index('Date')
    idx =(pd.MultiIndex.from_product(df.index.str.split(',', expand=True).levels)
            .map(','.join))
    
    df = df.reindex(idx, fill_value=0).rename_axis('Date').reset_index()
    print (df.head())
          Date  Churn  Churnrate  customerID
    0  2008,01  726.0   0.542398        2763
    1  2008,02  345.0   0.257751        1351
    2  2008,03    0.0   0.000000           0
    3  2008,04    0.0   0.000000           0
    4  2008,05    0.0   0.000000           0
    

    编辑:通过range(1,13) 定义所有Months 的解决方案

    df = df.set_index('Months')
    years = df.index.str.split('/', expand=True).levels[0]
    idx = (pd.MultiIndex.from_product([years, 
                                      pd.Series(range(1, 13)).astype(str).str.zfill(2)])
            .map('/'.join))
    
    df = df.reindex(idx, fill_value=0).rename_axis('Date').reset_index()
    print (df)
           Date  Retention_Rate  Customer_Count
    0   2008/01        0.145916             133
    1   2008/02        0.924663             762
    2   2008/03        0.074544              67
    3   2008/04        0.000000               0
    4   2008/05        0.000000               0
    5   2008/06        0.000000               0
    6   2008/07        0.000000               0
    7   2008/08        0.000000               0
    8   2008/09        0.000000               0
    9   2008/10        0.000000               0
    10  2008/11        0.000000               0
    11  2008/12        0.000000               0
    12  2014/01        0.000000               0
    13  2014/02        0.000000               0
    14  2014/03        0.000000               0
    15  2014/04        0.000000               0
    16  2014/05        0.000000               0
    17  2014/06        0.000000               0
    18  2014/07        0.058684              45
    19  2014/08        0.069786              61
    20  2014/09        0.076130              64
    21  2014/10        0.061856              60
    22  2014/11        0.082474              69
    23  2014/12        0.000000               0
    

    如果需要用零替换缺失的年份和对应的列:

    print (df)
    Year   Churn_Count  Churn_Rate  Customer_Count                                        
    2008       1071.0    0.800149             4114
    2012          0.0    0.000000                6
    2013        233.0    0.174075              824
    2014        101.0    0.075458              410
    

    然后使用:

    df1 = (df.set_index('Year')
            .reindex(range(2008, 2015), fill_value=0)
            .reset_index())
    print (df1)
       Year  Churn_Count  Churn_Rate  Customer_Count
    0  2008       1071.0    0.800149            4114
    1  2009          0.0    0.000000               0
    2  2010          0.0    0.000000               0
    3  2011          0.0    0.000000               0
    4  2012          0.0    0.000000               6
    5  2013        233.0    0.174075             824
    6  2014        101.0    0.075458             410
    

    reindex 的更多动态解决方案(按最小和最大年份):

    df1 = df.set_index('Year')
    df1 = (df1.reindex(range(df1.index.min(), df1.index.max() + 1), fill_value=0)
              .reset_index())
    print (df1)
       Year  Churn_Count  Churn_Rate  Customer_Count
    0  2008       1071.0    0.800149            4114
    1  2009          0.0    0.000000               0
    2  2010          0.0    0.000000               0
    3  2011          0.0    0.000000               0
    4  2012          0.0    0.000000               6
    5  2013        233.0    0.174075             824
    6  2014        101.0    0.075458             410
    

    【讨论】:

    • 它正在工作但只显示这5条记录,剩余的记录呢?像 2008 年,所有月份和其他年份都是 06,08?
    • @sangeethasivakumar - 使用print (df)
    • 对不起@jezrael 我没有注意到。
    • @sangeethasivakumar - 没问题,如果我的回答有帮助,请不要忘记accept 它 - 单击答案旁边的复选标记 (v) 将其从灰色切换为填充在。谢谢。
    • @sangeethasivakumar - 非常感谢。
    【解决方案2】:

    我认为另一种简单的方法可能是这样。

    import pandas as pd
    df = pd.DataFrame({"date":["2010-01", "2010-02", "2011-01"], 
                       "a": [1, 2, 3], 
                       "b":[0.2,-0.1,0.4]})
    df["date"] = pd.to_datetime(df["date"])
    all_dates = pd.DataFrame({"date":pd.date_range(start=df["date"].min(), 
                                                   end=df["date"].max(), 
                                                   freq="MS")})
    df = pd.merge(all_dates, df, how="left", on="date").fillna(0)
    

    如果date 是您的索引,您可以使用.reset_index().set_index()。然后,如果您想保持相同的日期格式,只需添加 df["date"] = df["date"].dt.strftime("%Y-%m")

    【讨论】:

    • df["date"] = df["date"].dt.strftime("%Y-%m") 我只使用这种格式
    • @sangeethasivakumar 正如我在回答末尾所说的那样。这个解决方案不适合你的情况吗?
    猜你喜欢
    • 2020-02-08
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多