所有 - 我希望您能够提供帮助,因为这是我知道我几乎已经从这里和网上的各种帖子中破解的任务之一,但还没有完全发挥作用。
本质上,我在数据库中有以下数据,这些数据通过 psql.read_sql(sql, cnxn) 返回到 Pandas 对象
+------------------------------------+
| StartTime StartLevel |
+------------------------------------+
| 0 2015-02-16 00:00:00 480.000 |
| 1 2015-02-16 00:30:00 480.000 |
| 2 2015-02-16 00:34:00 390.000 |
| 3 2015-02-16 01:00:00 390.000 |
| 4 2015-02-16 01:30:00 390.000 |
| 5 2015-02-16 02:00:00 480.000 |
| 6 2015-02-16 02:17:00 420.000 |
+------------------------------------+
StartTime datetime64[ns]
StartLevel float64
dtype: object
我只是想对上述数据进行逐分钟的插值。
我还以分钟频率创建了一个日期时间系列,但在我的一生中,我无法将我的表“映射”到此上,然后进行插值,或者如何将 StartTime 重新采样为分钟粒度,然后进行插值缺失的数据。
任何帮助将不胜感激(我确信当我找到解决方案时我会踢自己!) - 非常感谢
更新
按照下面的建议,代码如下:
import datetime
import numpy as np
import pandas as pd
import pyodbc
import pandas.io.sql as psql
cnxn = pyodbc.connect('DSN=MySQL;DATABASE=db;UID=uid;PWD=pwd')
cursor = cnxn.cursor()
sql = """
SELECT
StartTime,StartLevel
FROM
aa.bb
where cc = 'dd'
and StartTime < '2015-02-16 02:30:00'
order by StartTime asc"""
old_df = psql.read_sql(sql, cnxn)
num_minutes = 120
base = datetime.datetime(2015, 02, 16, 00, 00, 00)
date_list = [base + datetime.timedelta(minutes=x) for x in range(0, num_minutes)]
# set num_minutes for whatever is the correct number of minutes you require
new_data = [dict(StartTime=d, fake_val=np.NaN) for d in date_list]
new_df = pd.DataFrame(new_data)
new_df['StartLevel'] = old_df['StartLevel']
new_df.interpolate(inplace=True)
new_df 在提示符下的输出是:
+-----------------------------------------------+
| StartTime fake_val StartLevel |
+-----------------------------------------------+
| 0 2015-02-16 00:00:00 NaN 480 |
| 1 2015-02-16 00:01:00 NaN 480 |
| 2 2015-02-16 00:02:00 NaN 390 |
| 3 2015-02-16 00:03:00 NaN 390 |
| 4 2015-02-16 00:04:00 NaN 390 |
| 5 2015-02-16 00:05:00 NaN 480 |
| 6 2015-02-16 00:06:00 NaN 480 |
+-----------------------------------------------+
最佳答案
我很确定这不是最Pythonic的答案,所以我欢迎评论来改进它,但我相信你可以做这样的事情
首先创建您想要值的所有日期时间对象
num_minutes = 120
base = datetime.datetime(2015, 02, 16, 00, 00, 00)
date_list = [base + datetime.timedelta(minutes=x) for x in range(0, num_minutes)]
# set num_minutes for whatever is the correct number of minutes you require
然后使用这些索引值创建一个“假”数据框
new_data = [dict(StartTime=d, fake_val=np.NaN) for d in date_list]
new_df = pd.DataFrame(new_data)
编辑:更正响应
现在我们想要将两个数据帧合并为一个(并按日期排序):
final_df = new_df.merge(df, how='outer', on='date').sort(columns='date')
final_df
现在将按日期排序,并在您有数据时包含 StartLevel
的正确值,在没有数据时包含 NaN
的值其数据。然后你可以调用interpolate
编辑:默认情况下,插值不会被称为inplace
,因此您需要设置该标志或保存结果
final_df = final_df.interpolate()
或
final_df.interpolate(inplace=True)
显然,一旦您合并了正确的数据,fake_val
列就可以被丢弃。创建该数据帧的目的是让一个数据帧包含您想要的所有值(这是我确信有一个更Pythonic的答案的地方)
可以找到插值
的完整文档here
关于python - 在Python中插入缺失值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28567854/