在DataFrame中插入缺少的日期并转换为数组

时间:2019-07-09 17:36:58

标签: python pandas

我有一个这样的DataFrame:

Buying_date Event_date  Number_of_tickets_sold

12/11/2018  01/01/2019  2

20/01/2019  24/03/2019  1

13/11/2018  01/01/2019  3

21/12/2018  01/01/2019  2

01/01/2019  10/01/2019  4

20/02/2019  21/02/2019  2

01/03/2019  24/03/2019  3

在每个活动日期之前90天释放门票。有几天没有人买票,但是我想将90天到0天之间的每一天都包含在Buying_date列中,并将那几天的相应Number_of_tickets_sold设置为0。 之后,我想为每个事件创建一个Number_of_tickets_sold的Numpy数组。因此,如果有10个事件,那么将有10个数组,每个数组都有90个值。

请帮助解决问题!

2019年1月1日事件的数组:

np.array([0, 0 , 1, 3, 2....])

2 个答案:

答案 0 :(得分:0)

现在,这可能变得有点复杂了:)

假设您的数据位于数据框“ df”中

让我们创建一个数据框,其中包含所有事件日期和该日期之后的90天

list_data=[pd.concat([pd.Series(pd.to_datetime(k)).repeat(90).reset_index()[0], \
pd.Series(pd.date_range(pd.to_datetime(k)-datetime.timedelta(90),\
                        periods=90,freq='D')).reset_index()[0]],axis=1) for k in df.Event_Date]

my_need=pd.concat(list_data)
my_need.columns=['Event_Date','Buying_Date']

将数据类型转换为日期格式

df['Event_Date']=df['Event_Date'].astype('datetime64')
df['Buying_Date']=df['Buying_Date'].astype('datetime64')

让我们合并,然后用0填充NAs

final=pd.merge(my_need,df,how='left')
final.fillna(0,inplace=True)

希望这就是您想要的。

答案 1 :(得分:0)

您可以这样做,例如:

def resample(g, date):
    return g.reindex(pd.date_range(end=date, freq='D', periods=90)).fillna(0)

for date, g in (df["Number_of_tickets_sold"].groupby(df['Event_date'])):
    print(resample(g, date))

对于每个活动,这将为您提供每天的门票销售系列,并按日期编制索引。如果您不在乎索引,可以执行以下操作:

def resample(g, date):
    return (g.reindex(pd.date_range(end=date, freq='D', periods=90))
             .fillna(0)
             .reset_index(drop=True)
           )

pd.DataFrame({date:resample(g, date) for date,g in df["Number_of_tickets_sold"]
              .groupby(df['Event_date'])})

然后,您将拥有一个像这样的数据框:

    2019-01-01  2019-02-21  2019-03-24  2019-10-01
0          0.0         0.0         0.0         0.0
1          0.0         0.0         0.0         0.0
2          0.0         0.0         0.0         0.0
3          0.0         0.0         0.0         0.0
4          0.0         0.0         0.0         0.0
5          0.0         0.0         0.0         0.0

其中的列是每天每个事件的每日门票销售。

如果您希望使用与原始数据相同的格式:

def resample(g):
    dates = pd.date_range(end=g['Event_date'][0], freq='D', periods=90)
    return g['Number_of_tickets_sold'].reindex(dates).fillna(0)

(df.set_index('Buying_date')
   .groupby('Event_date')
   .apply(resample)
   .reset_index()
)

会给你

    Event_date    level_1  Number_of_tickets_sold
0   2019-01-01 2018-10-04                     0.0
1   2019-01-01 2018-10-05                     0.0
2   2019-01-01 2018-10-06                     0.0
3   2019-01-01 2018-10-07                     0.0
4   2019-01-01 2018-10-08                     0.0
5   2019-01-01 2018-10-09                     0.0

其中level_1列是销售日期。