我有一个大约9k行和57列的数据框,这是' df'。
我需要一个新的数据框:' df_final' - 对于每一行' df'我必须复制每一行' x'时间和逐行增加每一天的日期,也是' x'倍。 虽然我可以进行几次迭代,但是当我在全长时间内完成这些迭代时,我会这样做。 ' LEN(DF)'这个循环花了这么长时间(> 3小时)我实际上不得不取消它。我从未见过它的结束。这是当前的代码:
df.shape
output: (9454, 57)
df_int = df[0:0]
df_final = df_int[0:0]
range_df = len(df)
for x in range(0,2):
df_int = df.iloc[0+x:x+1]
if abs(df_int.iat[-1,3]) > 0:
df_int = pd.concat([df_int]*abs(df_int.iat[-1,3]), ignore_index=True)
for i in range(1, abs(df_int.iat[-1,3])):
df_int['Consumption Date'][i] = df_int['Consumption Date'][i-1] + datetime.timedelta(days = 1)
i += 1
df_final = df_final.append(df_int, ignore_index=True)
x += 1
前两行&#39>的循环结果。 DF'在下面。
是否有其他方法可以达到所需的输出。似乎熊猫不能很好地处理循环。在VBA excel中,相同的循环需要大约3/4分钟...我正在尝试将目前处于excel的进程更改为python,但是,如果没有办法使这项工作我想我会坚持旧方式......
答案 0 :(得分:3)
使用repeat
和cumcount
In [2972]: dff = df.loc[df.index.repeat(3)]
In [2973]: dff
Out[2973]:
date name
0 2017-05-03 bob
0 2017-05-03 bob
0 2017-05-03 bob
1 2017-06-13 sally
1 2017-06-13 sally
1 2017-06-13 sally
In [2974]: dff.loc[:, 'date'] += pd.to_timedelta(dff.groupby(level=0).cumcount(), 'D')
In [2975]: dff
Out[2975]:
date name
0 2017-05-03 bob
0 2017-05-04 bob
0 2017-05-05 bob
1 2017-06-13 sally
1 2017-06-14 sally
1 2017-06-15 sally
详细
In [2976]: df
Out[2976]:
date name
0 2017-05-03 bob
1 2017-06-13 sally
In [2977]: dff.groupby(level=0).cumcount()
Out[2977]:
0 0
0 1
0 2
1 0
1 1
1 2
dtype: int64
答案 1 :(得分:1)
让我们使用这个玩具DataFrame:
df = pd.DataFrame({
'date': pd.to_datetime(['2017-05-03', '2017-06-13']),
'name': ['bob', 'sally'],
})
看起来像这样:
date name
0 2017-05-03 bob
1 2017-06-13 sally
然后:
x = 3 # repeat count
ind = np.repeat(np.arange(len(df)), x) # 0,0,0,1,1,1
df_final = df.iloc[ind].copy()
这给你重复:
date name
0 2017-05-03 bob
0 2017-05-03 bob
0 2017-05-03 bob
1 2017-06-13 sally
1 2017-06-13 sally
1 2017-06-13 sally
现在你只需要增加日期:
inc = np.tile(np.arange(x), len(df)) # 0,1,2,0,1,2
df_final.date += pd.to_timedelta(inc, 'D')
你得到:
date name
0 2017-05-03 bob
0 2017-05-04 bob
0 2017-05-05 bob
1 2017-06-13 sally
1 2017-06-14 sally
1 2017-06-15 sally
答案 2 :(得分:1)
这是一个解决方案
df1=df.reset_index().set_index('date').groupby('index').\
apply(lambda x :x.reindex(pd.date_range(start=x.index[0],periods=3,freq='D'))).ffill()
df1
Out[202]:
index name
index
0 2017-05-03 0.0 bob
2017-05-04 0.0 bob
2017-05-05 0.0 bob
1 2017-06-13 1.0 sally
2017-06-14 1.0 sally
2017-06-15 1.0 sally
然后
df1.drop('index',1).reset_index().rename(columns={'level_1':'date'}).drop('index',1)
Out[212]:
date name
0 2017-05-03 bob
1 2017-05-04 bob
2 2017-05-05 bob
3 2017-06-13 sally
4 2017-06-14 sally
5 2017-06-15 sally