我目前有一个具有以下通用格式的数据框:
id,transaction_dt,units,measure
1,2014-01-06,30,30.5
1,2014-02-04,5,22.6
我希望完成以下内容:
根据id将天数添加到transaction_dt创建新记录,以创建如下所示的结果数据框:
id,enumerated_dt,measure
1,2014-01-06,30.5
1,2014-01-07,30.5
1,2014-01-08,30.5
...
1,2014-02-05,30.5
1,2014-02-04,22.6
1,2014-02-05,22.6
...
我认为堆栈可能是解决方案的一部分,但我目前难以理解如何以高效的方式枚举/增加日期。任何建议或解决方案将非常感谢!
答案 0 :(得分:1)
编辑:乍一看,看起来您确实希望填补日期中的空白,然后向前填充数据,这可以轻松完成:
df.set_index('transaction_dt').resample('D').ffill()
但是,如果您不想创建连续索引,而是要添加任意数量的行N
,则可以先将'transaction_dt'移动到索引来执行此操作:
df.set_index('transaction_dt', inplace=True)
...然后使用这个lambda函数(使用numpy方法):
add_n_dates = lambda n: df.index.repeat(n) + \
np.tile(np.arange(n)*pd.Timedelta('1 days'), df.index.size)
...在最终重新索引+前向填充之前,为新索引的每个元素添加n
个日期:
df.reindex(add_n_dates(5), method='ffill')
# id units measure
# transaction_dt
# 2014-01-06 1.0 30.0 30.5
# 2014-01-07 1.0 30.0 30.5
# 2014-01-08 1.0 30.0 30.5
# 2014-01-09 1.0 30.0 30.5
# 2014-01-10 1.0 30.0 30.5
# 2014-02-04 1.0 5.0 22.6
# 2014-02-05 1.0 5.0 22.6
# 2014-02-06 1.0 5.0 22.6
# 2014-02-07 1.0 5.0 22.6
# 2014-02-08 1.0 5.0 22.6
编辑#2:
再次假设您已将索引设置为transaction_dt
,这可能是使用units
中的值来确定要添加的行数的最简单方法。它使用pd.date_range
创建必要的日期值,方法是将row.name
(即其索引值)作为起点,将row.units
作为要生成的句点数。{/ p>
df.apply(lambda x: pd.Series(pd.date_range(x.name, periods=x.units)), axis=1). \
stack(). \
reset_index(level=1). \
join(df['measure']). \
drop('level_1', axis=1). \
reset_index(). \
rename(columns={0:'enumerated_dt'})
# transaction_dt enumerated_dt measure
# 0 2014-01-06 2014-01-06 30.5
# 1 2014-01-06 2014-01-07 30.5
# 2 2014-01-06 2014-01-08 30.5
# 3 2014-01-06 2014-01-09 30.5
# 4 2014-01-06 2014-01-10 30.5
# ...
# 29 2014-01-06 2014-02-04 30.5
# 30 2014-02-04 2014-02-04 22.6
# 31 2014-02-04 2014-02-05 22.6
# 32 2014-02-04 2014-02-06 22.6
# 33 2014-02-04 2014-02-07 22.6
# 34 2014-02-04 2014-02-08 22.6
答案 1 :(得分:1)
您可以创建帮助数据框
test_numpy_array = np.array([[2,3,4,5],
[6,4,1,2],
[3,4,5,1],
[8,9,7,6],
[4,1,2,5]])