【问题标题】:How to impute default values to Pandas dataframe columns?如何将默认值归入 Pandas 数据框列?
【发布时间】:2020-02-17 07:33:46
【问题描述】:

以下是将日期设置为索引的 DataSet 的 df.head()

               Article_ID Country_Code Sold_Units
     Date           
2017-01-01        3576        AT         1
2017-01-02        1579        FR         1
2017-01-02         332        FI         2
2017-01-03        3576        AT         1
2017-01-03         332        SE         1

国家代码有 4 个值“AT、FR、FI、SE”。如果这 4 个国家/地区代码在这些日期不存在,我想将它们附加到每个日期,并在 Article_ID 和 Sold_Units 中将它们的值归为 0。

示例输出基本上应该是这样的:

               Article_ID Country_Code Sold_Units
     Date           
2017-01-01        3576        AT         1
2017-01-01          0         FR         0    # FR FI SE added with 0s.
2017-01-01          0         FI         0
2017-01-01          0         SE         0
2017-01-02          0         AT         0    # AT, SE added
2017-01-02        1579        FR         1
2017-01-02         332        FI         2
2017-01-02          0         SE         0
2017-01-03        3576        AT         1
2017-01-03          0         FR         0    # FR, FI added
2017-01-03          0         FI         0
2017-01-03         332        SE         1

如何为每个国家/地区代码添加这样的默认值?

【问题讨论】:

    标签: python pandas dataframe imputation


    【解决方案1】:

    使用pivot_table的另一种解决方案:

    import pandas as pd
    
    df = pd.DataFrame({'Date': {0: '2017-01-01', 1: '2017-01-02', 2: '2017-01-02', 3: '2017-01-03', 4: '2017-01-03'},
                       'Article_ID': {0: 3576, 1: 1579, 2: 332, 3: 3576, 4: 332},
                       'Country_Code': {0: 'AT', 1: 'FR', 2: 'FI', 3: 'AT', 4: 'SE'},
                       'Sold_Units': {0: 1, 1: 1, 2: 2, 3: 1, 4: 1}})
    
    df.set_index("Date",inplace=True)
    
    result = (df.pivot_table(index="Date", columns="Country_Code", values=["Article_ID","Sold_Units"],aggfunc="mean")
             .fillna("0").stack().reset_index(level=1))
    
    print (result)
    
    #
               Country_Code Article_ID Sold_Units
    Date                                         
    2017-01-01           AT       3576          1
    2017-01-01           FI          0          0
    2017-01-01           FR          0          0
    2017-01-01           SE          0          0
    2017-01-02           AT          0          0
    2017-01-02           FI        332          2
    2017-01-02           FR       1579          1
    2017-01-02           SE          0          0
    2017-01-03           AT       3576          1
    2017-01-03           FI          0          0
    2017-01-03           FR          0          0
    2017-01-03           SE        332          1
    

    【讨论】:

    • 抛出 KeyError: 'Date' 因为日期已设置为索引。
    • 这更容易 - 只需删除 index="Date" 部分。
    • 嗯,也许最好的说法是关于聚合平均值
    • ValueError: cannot handle a non-unique multi-index!
    • 奇怪。如果我按照 jezrael 的建议将 aggfunc="mean" 更改为 pivot_table 是否有效?只是想知道为什么它不起作用:)
    【解决方案2】:

    独特的DatetimeIndexCountry_Code 组合的解决方案:

    通过将Country_Code 添加到DatetimeIndex 来创建MultiIndex,并使用带有DataFrame.reindex 代码的日期时间唯一值的所有组合:

    df = (df.set_index('Country_Code', append=True)
            .reindex(pd.MultiIndex.from_product([df.index.unique(), df['Country_Code'].unique()], 
                                                names=['Date','Country_Code']), fill_value=0)
            .reset_index(level=1))
    print (df)
               Country_Code  Article_ID  Sold_Units
    Date                                           
    2017-01-01           AT        3576           1
    2017-01-01           FR           0           0
    2017-01-01           FI           0           0
    2017-01-01           SE           0           0
    2017-01-02           AT           0           0
    2017-01-02           FR        1579           1
    2017-01-02           FI         332           2
    2017-01-02           SE           0           0
    2017-01-03           AT        3576           1
    2017-01-03           FR           0           0
    2017-01-03           FI           0           0
    2017-01-03           SE         332           1
    

    或将DataFrame.unstackDataFrame.stack:

    df = (df.set_index('Country_Code', append=True)
            .unstack(fill_value=0)
            .stack()
            .reset_index(level=1))
    
    print (df)
               Country_Code  Article_ID  Sold_Units
    Date                                           
    2017-01-01           AT        3576           1
    2017-01-01           FI           0           0
    2017-01-01           FR           0           0
    2017-01-01           SE           0           0
    2017-01-02           AT           0           0
    2017-01-02           FI         332           2
    2017-01-02           FR        1579           1
    2017-01-02           SE           0           0
    2017-01-03           AT        3576           1
    2017-01-03           FI           0           0
    2017-01-03           FR           0           0
    2017-01-03           SE         332           1
    

    每个日期时间使用国家代码的多个值的解决方案:

    错误表示数据如下:

    print (df)
                Article_ID Country_Code  Sold_Units
    Date                                           
    2017-01-01        3576           AT           1
    2017-01-02        1579           FI           1 <-FI
    2017-01-02         332           FI           2 <-FI
    2017-01-03        3576           AT           1
    2017-01-03         332           SE           1
    

    df = (df.groupby(['Date','Country_Code'])
            .sum()
            .unstack(fill_value=0)
            .stack()
            .reset_index(level=1))
    print (df)
               Country_Code  Article_ID  Sold_Units
    Date                                           
    2017-01-01           AT        3576           1
    2017-01-01           FI           0           0
    2017-01-01           SE           0           0
    2017-01-02           AT           0           0
    2017-01-02           FI        1911           3
    2017-01-02           SE           0           0
    2017-01-03           AT        3576           1
    2017-01-03           FI           0           0
    2017-01-03           SE         332           1
    

    【讨论】:

    • 第一个选项返回:ValueError: cannot handle a non-unique multi-index!第二个选项返回:ValueError: Index contains duplicate entries, cannot reshape
    • @hammeroflight - 所以这意味着Country_CodeDate 存在重复。
    • 是的,有 4 个国家在销售一种产品。有些日期有一些国家不销售,需要用 0 估算。每个日期可以有多个国家代码。
    • @hammeroflight - 我认为问题就像第二行将FR 更改为FI - 然后将FI 加倍2017-01-02
    • 不,您的代码正是我们所需要的。完美使用 stack 和 unstack。
    猜你喜欢
    • 1970-01-01
    • 2016-04-25
    • 2016-09-01
    • 2022-07-21
    • 1970-01-01
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多