在Python中插入缺失值

时间:2015-02-17 17:52:49

标签: python scipy linear-interpolation pandasql

全部 - 我希望你能够提供帮助,因为这是我知道我几乎已经从这里和网上的各种帖子中解脱出来的任务之一,但还没有完全发挥作用。

基本上,我在通过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 |
+-----------------------------------------------+

1 个答案:

答案 0 :(得分:0)

我很确定这不是最狡猾的答案,所以我欢迎评论来改进它,但我相信你可以做这样的事情

首先创建所需的所有日期时间对象

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

然后创建一个&#34;假的&#34;具有这些索引值的数据框

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

编辑:默认情况下,Interpolate不会被称为inplace,因此您需要设置该标志或保存结果

final_df = final_df.interpolate()

final_df.interpolate(inplace=True)

显然,一旦您在好数据中合并,fake_val列就会被抛弃。创建该数据框的目的是为一个索引所有您想要的值(这是我确定有更多pythonic答案的地方)

可以找到interpolate的完整文档here