同时填充缺失的日期和桶

我有一个像这样的数据框


Start_MONTH  Bucket Count Complete Partial


 10/01/2015      0       57     91      0.66


 11/01/2015      0       678    8       0.99


 02/01/2016      0        68    12       0.12


 10/01/2015      1       78     79      0.22


 11/01/2015      1       99     56     0.67


 1/01/2016       1       789    67     0.78


 10/01/2015      3       678    178    0.780


11/01/2015       3       2880   578     0.678

我基本上需要填写每个 start_month (缺少 12/01/2015,01/01/2016 ,...)并且每个像 2 这样的桶都丢失了,其余的列(计数,完整,部分)将为零缺少存储桶和 start_month。我认为使用relativedelta(months=+1) 会有所帮助,但不确定如何使用它。


pandas as pd

data =  [['10/01/2015',0 ,57 ,91,0.66],

 ['11/01/2015',0, 678, 8,0.99],

  ['02/01/2016',0,68,12,0.12],

  ['10/01/2015' ,1, 78,79,0.22],

  ['11/01/2015' ,1 ,99,56, 0.67],

  ['1/01/2016', 1 ,789,67,0.78],

  ['10/01/2015', 3,678, 178, 0.780],

  ['11/01/2015' ,3, 2880,578,0.678]]

df = pd.DataFrame(data, columns = ['Start_Month', 'Bucket', 'Count', 

'Complete','Partial']) 

基本上我希望 Start_month 和存储桶组都作为一个组重复,其他值为 0,即从 10/01/2015 到 2/1/2016(缺少 12/01/2015,01/01/2016)所有月份在那里并且 0-3 的桶(缺少 2)都需要在那里

https://img3.mukewang.com/64d1a0f900019ee609090452.jpg

我尝试了这个,它部分地满足了我的要求


df['Start_Month'] = pd.to_datetime(df['Start_Month'])

s = df.groupby(['Bucket',pd.Grouper(key='Start_Month', freq='MS')])['Count','Complete','Partial'].sum()

df1 = (s.reset_index(level=0)

    .groupby('Bucket')['Count','Complete','Partial']

    .apply(lambda x: x.asfreq('MS'))

    .reset_index())

它添加了一些缺失的月份,但不会对每个存储桶重复,并且不会在其间添加存储桶整数


喵喵时光机
浏览 98回答 2
2回答

牛魔王的故事

起始 dfdata =  [    ['10/01/2015',0 ,57 ,91,0.66],    ['11/01/2015',0, 678, 8,0.99],    ['02/01/2016',0,68,12,0.12],    ['10/01/2015' ,1, 78,79,0.22],    ['11/01/2015' ,1 ,99,56, 0.67],    ['1/01/2016', 1 ,789,67,0.78],    ['10/01/2015', 3,678, 178, 0.780],    ['11/01/2015' ,3, 2880,578,0.678]]df = pd.DataFrame(data, columns=['Start_Month', 'Bucket', 'Count', 'Complete','Partial'])#.set_index('Start_Month')df['Start_Month'] = pd.to_datetime(df['Start_Month'])    Start_Month Bucket  Count   Complete    Partial0   2015-10-01     0      57        91       0.6601   2015-11-01     0      678        8       0.9902   2016-02-01     0      68        12       0.1203   2015-10-01     1      78        79       0.2204   2015-11-01     1      99        56       0.6705   2016-01-01     1      789       67       0.7806   2015-10-01     3      678      178       0.7807   2015-11-01     3      2880     578       0.678为存储桶 0 制作一个包含完整日期的单独 dfdf0 = pd.DataFrame([pd.date_range('2015-10-01', '2016-02-01', freq='MS'),                     [0]*5]).T.rename(columns={0: 'Start_Month', 1:'Bucket'})    Start_Month Bucket0   2015-10-01  01   2015-11-01  02   2015-12-01  03   2016-01-01  04   2016-02-01  0按相应日期和桶过滤原始 df 并将结果与 df0 合并df_filt = df[(df['Start_Month'].isin(df0['Start_Month'])) & (df['Bucket'] == 0)]df0 = pd.merge(df0, df_filt, left_on='Start_Month', right_on='Start_Month', how='outer')df0 = df0.drop('Bucket_y', axis=1).rename(columns={'Bucket_x': 'Bucket'})    Start_Month Bucket  Count   Complete Partial0   2015-10-01  0        57.0   91.0     0.661   2015-11-01  0        678.0  8.0      0.992   2015-12-01  0        NaN    NaN      NaN3   2016-01-01  0        NaN    NaN      NaN4   2016-02-01  0        68.0   12.0     0.12对存储桶 1、2 和 3 重复该过程,创建 df1、df2、df3。(由于重复而没有显示这一点......当然你可以循环执行此操作)。然后将所有 4 个 df 连接在一起,并用零填充 na。# Concatdf_final = pd.concat([df0, df1, df2, df3], axis=0).fillna(0)    Start_Month Bucket       Count   Complete   Partial0   2015-10-01       0       57.0        91.0   0.6601   2015-11-01       0       678.0       8.0    0.9902   2015-12-01       0       0.0         0.0    0.0003   2016-01-01       0       0.0         0.0    0.0004   2016-02-01       0       68.0        12.0   0.1200   2015-10-01       1       78.0        79.0   0.2201   2015-11-01       1       99.0        56.0   0.6702   2015-12-01       1       0.0         0.0    0.0003   2016-01-01       1       789.0       67.0   0.7804   2016-02-01       1       0.0         0.0    0.0000   2015-10-01       2       0.0         0.0    0.0001   2015-11-01       2       0.0         0.0    0.0002   2015-12-01       2       0.0         0.0    0.0003   2016-01-01       2       0.0         0.0    0.0004   2016-02-01       2       0.0         0.0    0.0000   2015-10-01       3       678.0       178.0  0.7801   2015-11-01       3       2880.0      578.0  0.6782   2015-12-01       3       0.0         0.0    0.0003   2016-01-01       3       0.0         0.0    0.0004   2016-02-01       3       0.0         0.0    0.000更新:显示完全循环的代码,并在评论中回答您的问题。def get_separate_df(df, bucket_num):    df_bucket = pd.DataFrame([pd.date_range('2015-10-01', '2016-02-01', freq='MS'),                         [bucket_num]*5]).T.rename(columns={0: 'Start_Month', 1:'Bucket'})    df_filt = df[(df['Start_Month'].isin(df_bucket['Start_Month'])) & \                        (df['Bucket'] == bucket_num)]    df_bucket = pd.merge(df_bucket, df_filt, left_on='Start_Month', right_on='Start_Month', how='outer')    df_bucket = df_bucket.drop('Bucket_y', axis=1).rename(columns={'Bucket_x': 'Bucket'})    return df_bucketdfs = [get_separate_df(df, i) for i in range(4)] # Concatdf_final = pd.concat(dfs, axis=0).fillna(0)至于评论中的问题,您可以获得一个空数据框,其中包含重复的日期和存储桶序列,如下所示:bucket_list = [ele for ele in [0,1,2,3] for i in range(5)]dates = list(pd.date_range('2015-10-01', '2016-02-01', freq='MS'))*4df = pd.DataFrame(data=[dates, bucket_list]).T.rename(columns={0:'Start_Month', 1:'Bucket'})Output:    Start_Month Bucket0   2015-10-01  01   2015-11-01  02   2015-12-01  03   2016-01-01  04   2016-02-01  05   2015-10-01  16   2015-11-01  17   2015-12-01  18   2016-01-01  19   2016-02-01  110  2015-10-01  211  2015-11-01  212  2015-12-01  213  2016-01-01  214  2016-02-01  215  2015-10-01  316  2015-11-01  317  2015-12-01  318  2016-01-01  319  2016-02-01  3

UYOU

写了一篇类似的文章,但只是概括了一点 import pandas as pd import numpy as np # converting date string to date df['Start_Month'] = pd.to_datetime(df['Start_Month']) # finding the the date range and increasin by 1 month start rng = pd.date_range(df['Start_Month'].min(),df['Start_Month'].max(), freq='MS') # creating date dataframe df1 = pd.DataFrame({ 'Start_Month': rng}) # Converting bucket field to integer df['Bucket'] = df['Bucket'].astype(int) # finding the bucket values max and minBucket=np.arange(df['Bucket'].min(),df['Bucket'].max()+1,1) # Repeating the date range for every bucketdf1=pd.concat([df1]*len(Bucket)) # repeating bucket values to each datedf1['Bucket']=np.repeat(Bucket, len(rng))# merging to the previous dataframe and filling it with 0merged_left = pd.merge(left=df1, right=df, how='left', on=['Start_Month','Bucket']).fillna(0)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python