【发布时间】:2018-07-29 19:01:47
【问题描述】:
我有一个大约 40,000 行的 DataFrame。 DataFrame 大致如下:
Unix Time UTC Val. 1 Val. 2 Val. 3
1 1518544176.927486 2018-02-13 17:49:36.927486 5.00 0.25 2.00
2 1518544176.929897 2018-02-13 17:49:36.929897 4.50 1.00 3.00
3 1518544176.932310 2018-02-13 17:49:36.932310 4.00 0.75 1.75
...
第 0、2-4 列是类型 <class 'numpy.float64'>。第 1 列是类型 <class 'pandas._libs.tslib.Timestamp'>。当绘制任何数据列与时间的关系时,我们会看到一个波形。但是,收购中偶尔会出现中断。例如,我们可能有:
Unix Time UTC Val. 1 Val. 2 Val. 3
576 1518544181.755085 2018-02-13 17:49:41.755085 0.10 0.01 0.93
577 1518544182.041129 2018-02-13 17:49:42.041129 0.11 0.02 0.95
...
如您所见,读数 576 和 577 之间存在约 0.3 秒的差距。问题在于,在绘制数据时,matplotlib 会连接点,即使没有数据。这个“问题”的解决方案已经在 Stack Overflow 和网上的其他问题中得到解决,虽然我不喜欢......好吧,任何一个,最好的选择似乎是将 NaN 插入数据缺口。由于 matplotlib 不绘制 NaN,这是一种偷偷摸摸的方式来欺骗它,让你的情节更真实。
为此,我首先找到前两个读数之间的时间差(这是安全的),然后使用该值的两倍作为“是否存在间隙?”的指标。然后我遍历 DataFrame,检查差距。找到一个后,我在数据列中创建了一个临时的 NaN 行,并在时间列的采集间隙中间创建了时间值。然后,我修改了一个由旧 DataFrame 和这一行组成的新 DataFrame。可以在这里看到:
df2 = df.copy()
for i, row in df.iterrows():
# The following code checks the delta-t of all timestamp pairs.
# We have i > 0 because it can't activate on the first entry.
if i > 0:
delta_t_unix = row['Unix Time'] - prev_timestamp_unix
delta_t_utc = row['UTC'] - prev_timestamp_utc
# If delta_t_unix > the allowed data gap, add new timestamps and NaNs.
if delta_t_unix > allowed_gap:
time_unix = row['Unix Time'] - (delta_t_unix / 2.0)
time_utc = row['UTC'] - (delta_t_utc / 2.0)
val1 = np.nan
val2 = np.nan
val3 = np.nan
new_row = pd.DataFrame({'Unix Time': time_unix, 'UTC': time_utc,
'Val. 1': val1, 'Val. 2': val2,
'Val. 3': val3}, index = [i])
df2 = pd.concat([df2.ix[:i-1], new_row,
df2.ix[i:]]).reset_index(drop = True)
# Set the previous timestamp for use in the beginning of the loop.
prev_timestamp_unix = row[timestamp_unix]
prev_timestamp_utc = row[timestamp_utc]
# Make the final DataFrame with the completed lists.
df2 = df2[['Unix Time', 'UTC', 'Val. 1', 'Val. 2', 'Val. 3']]
由于this question,这目前需要大约 4.5 秒(它过去需要大约 6.5 秒,因为我愚蠢地迭代并创建每列的新列表,然后从中创建一个新的 DataFrame)。但是,这仍然比我预期或喜欢的要慢得多。有人对如何加快速度有任何想法吗?我对 Pandas 和 DataFrames 还是很陌生,所以我相信这可能会更好。谢谢!
编辑:值得一提的是,如果我删除 datetime 列,它会将时间分成两半(但不幸的是,我无法在实践中删除它)。
【问题讨论】:
-
其实,我很确定 pandas 有一个内置函数可以满足你的需求,我正在检查它,我会为你发布它
-
没有找到任何可以产生您所构建的东西的东西。我实际上错误地认为重新采样可以。
-
我已经更正了帖子中的一些错误,现在应该可以使用了。如果您能分享该代码运行多长时间,我将不胜感激。
标签: python python-3.x pandas dataframe