input = pd.DataFrame({
'Timestamp': [
pd.Timestamp('19/01/2022 10:00:00'),
pd.Timestamp('19/01/2022 10:00:00'),
pd.Timestamp('19/01/2022 15:00:00'),
pd.Timestamp('19/01/2022 15:30:00'),
pd.Timestamp('19/01/2022 16:00:00'),
pd.Timestamp('19/01/2022 19:30:00'),
pd.Timestamp('19/01/2022 20:00:00'),
pd.Timestamp('19/01/2022 20:30:00'),
pd.Timestamp('20/01/2022 13:00:00'),
pd.Timestamp('20/01/2022 13:30:00'),
pd.Timestamp('20/01/2022 14:00:00'),
pd.Timestamp('20/01/2022 14:50:00'),
pd.Timestamp('20/01/2022 15:00:00')],
'Name': [
'A', 'B', np.NaN, np.NaN, np.NaN,
'C', np.NaN, np.NaN, np.NaN, np.NaN, np.NaN,
'D', np.NaN]})
字符串
我正在尝试在时间戳之间同时向前填充多行,但我没有找到一个快速的方法来做到这一点。你能分享你的解决方案吗?
每一行对应于给定时间戳的一个名称条目。同一时间戳可以有多个名称。我想传播这组名称,直到下一个非nan值。
我尝试了一个简单的for循环,但这相对较慢(数组将有大约100,000行)。
所需输出为:
desired_output = pd.DataFrame({
'Timestamp': [
pd.Timestamp('19/01/2022 10:00:00'),
pd.Timestamp('19/01/2022 10:00:00'),
pd.Timestamp('19/01/2022 15:00:00'),
pd.Timestamp('19/01/2022 15:00:00'),
pd.Timestamp('19/01/2022 15:30:00'),
pd.Timestamp('19/01/2022 15:30:00'),
pd.Timestamp('19/01/2022 16:00:00'),
pd.Timestamp('19/01/2022 16:00:00'),
pd.Timestamp('19/01/2022 19:30:00'),
pd.Timestamp('19/01/2022 20:00:00'),
pd.Timestamp('19/01/2022 20:30:00'),
pd.Timestamp('20/01/2022 13:00:00'),
pd.Timestamp('20/01/2022 13:30:00'),
pd.Timestamp('20/01/2022 14:00:00'),
pd.Timestamp('20/01/2022 14:50:00'),
pd.Timestamp('20/01/2022 15:00:00')],
'Name': [
'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B',
'C', 'C', 'C', 'C', 'C', 'C',
'D', 'D']})
型
请在下面找到我的尝试:
import time
t0 = time.time()
unique_timestamps = input.Timestamp.unique()
new_entries = []
last_valid = None
for ut in unique_timestamps:
val = input[input.Timestamp == ut]['Name'].values
if type(val[0])==float and np.isnan(val[0]) and last_valid is not None:
new_entries.append(pd.DataFrame({'Timestamp': ut,
'Name': last_valid}))
else:
last_valid = input[input.Timestamp == ut]['Name']
output = pd.concat([input, pd.concat(new_entries)]).dropna().sort_values('Timestamp')
t1 = time.time()
print(str(t1-t0) + 's')
型
2条答案
按热度按时间2skhul331#
您可以按
Timestamp
和aggName
分组到一个集合中,然后按ffill和explode分组。我不知道如何最有效地做到这一点,但我发现最简单的方法是这样写的:
字符串
这遵循了你关于如何检测NaN的逻辑,即
pd.notna(s.iat[0])
取代了np.isnan(val[0])
。可能有更简单的方法来做到这一点,但我不确定它们是否有效,例如即使是lambda s: s
,我也很惊讶它的工作方式(单个元素变成标量,而多个元素变成数组)。测试结果:
型
qv7cva1a2#
合并
你可以de-duplicate键列(
Timestamp
),然后ffill它according to值(Name
),然后与原始的合并,这会处理多个值。这里我用ffill分配一个单独的列,只用作合并键。个字符
这与您的代码处理NaN的方式有点不同,但我不确定是否有任何实际差异。