根据多种条件将缺失数据添加到 pandas DataFrame

问题描述 投票:0回答:1

我有一个 pd.DataFrame ,如下所示:

                datetime ... month  year seconds
0    2023-03-02 20:59:00 ...     3  2023   75540
1    2023-03-02 20:58:00 ...     3  2023   75480
2    2023-03-02 20:57:00 ...     3  2023   75420
3    2023-03-02 20:56:00 ...     3  2023   75360
4    2023-03-02 20:55:00 ...     3  2023   75300
..                   ... ...   ...   ...     ...
775  2023-03-01 14:34:00 ...     3  2023   52440
776  2023-03-01 14:33:00 ...     3  2023   52380
777  2023-03-01 14:32:00 ...     3  2023   52320
778  2023-03-01 14:31:00 ...     3  2023   52260
779  2023-03-01 14:30:00 ...     3  2023   52200

[780 rows x 11 columns]

日期时间对象只能包含 14:30:00 到 20:59:00 之间的值。如果某些值超出此范围,则需要将其删除。 此外,两行之间的间隔每次都应该正好是 60 秒,除非从一天更改为另一天(当 df['seconds']== 52200 时)。请注意,数据可能跨越多天。

df 的第一行不一定是 20:59:00,例如可以从 16:30:00 开始。最后一行也是如此,这意味着它并不总是 14:30:00。 有些行随机丢失,我想添加它们。

日期时间、月、年、秒列应该是缺失的时间,而其他列中的值应该取其周围两行之间的值。比如说我们有:

                  datetime     x month  year seconds
299    2023-03-02 18:59:00   200     3  2023   68340
300    2023-03-02 18:56:00   230     3  2023   68160

我需要插入两行(因为秒数相差 180,所以缺少 2 分钟)。每行的 x 列应分别为 210 和 220。 我尝试使用 while 循环执行此操作,但效率极低 - 因为有时我的 df 超过 400'000 行。有没有办法使用 pandas 库或其他任何比迭代每对行、检查必须包含多少行,然后插入和重置索引更有效的方法?

python pandas dataframe missing-data
1个回答
0
投票

用途:

#convert to datetime
df['datetime'] = pd.to_datetime(df['datetime'])

#create MultiIndex by dates and seconds columns
out = df.set_index([df['datetime'].dt.normalize(), 'seconds'])

#create full MultiIndex by all combinations of all seconds and all existing dates
mux = pd.MultiIndex.from_product([out.index.levels[0], range(52200, 75540 +60, 60)],
                                 names=['date','seconds'])

#add missing rows
out = out.reindex(mux).reset_index()


#if necessary remove per dates rows before minimal seconds and after maximal seconds
mask = out['datetime'].notna()

out = out[mask.groupby(out['date']).cummax() & 
          mask.iloc[::-1].groupby(out['date'].iloc[::-1]).cummax().iloc[::-1]]

#interpolate x column
out['x'] = out['x'].interpolate()
#extract monts, years, count datetimes from seconds
out['month'] = out['date'].dt.month
out['year'] = out['date'].dt.year
out['datetime'] = out['date'] + pd.to_timedelta(out['seconds'], 'seconds')
© www.soinside.com 2019 - 2024. All rights reserved.