2015-12-31 77 views
3

我有定期将数据框拉进日期的日期。 数据通常是格式良好的,但有时在其他日期列中存在错误的数据。使用平均值填写数据框中的缺失日期

我总是期望在解析9位形式的日期:

(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1) 
(2015, 12, 29, 0, 30, 50, 1, 363, 0) 

我应该如何检查并解决这一问题?

我想要做的就是用基于表示last_update + 1/2更新间隔的变量的日期替换,这样项目不会被后面的函数过滤掉。

所示数据是从feedparser发布的。

import pandas as pd 
import datetime 

# date with ugly data 
df_date_ugly = pd.DataFrame({'date': [ 
          (2015, 12, 29, 0, 30, 50, 1, 363, 0), 
          (2015, 12, 28, 23, 59, 12, 0, 362, 0), 
          'None', '', 
          (2015, 12, 28, 23, 59, 12, 0, 362, 0) 
          ]}) 

# date is fine 
df_date = pd.DataFrame({'date': [ 
          (2015, 12, 29, 0, 30, 50, 1, 363, 0), 
          (2015, 12, 28, 23, 59, 12, 0, 362, 0), 
          (2015, 12, 28, 23, 59, 12, 0, 362, 0) 
          ]}) 

Pseudocode 
    if the original_date is valid 
    return original_date 
    else 
    return substitute_date 
+0

你可以编辑你的问题,以显示日期应该是怎么样的?具体而言,在(2015,12,29,0,30,50,1,363,0)中,您为什么要阅读(0,30,50,1,363,0) – imp9

+0

所示的数据是来自以下的published_pa​​rsed条目属性: feedparser,它来作为9整数。 – 12programmerwannabe

+0

1,363,0代表什么?你越解释越容易,每个人都可以帮助你,即使那些可能不熟悉feedparser但熟悉熊猫的人。另外,请在last_update + 1/2值中包含您所需的输出。 – imp9

回答

2
  1. 当日期和时间在大熊猫的工作,使用pandas.to_datetime其转换为pandas timestamp。要使用这个函数,我们将把列表转换为一个只有日期和时间元素的字符串。对于您的情况,不是长度为9的列表的值将被视为不好的并且被替换为空字符串''

    #convert list into string with date & time 
    #only elements with lists of length 9 will be parsed 
    dates_df = df_date_ugly.applymap(lambda x: "{0}/{1}/{2} {3}:{4}:{5}".format(x[0],x[1],x[2], x[3], x[4], x[5]) if len(x)==9 else '') 
    
    #convert to a pandas timestamp 
    dates_df = pd.to_datetime(dates_df['date'], errors = 'coerce')) 
    
        date 
    0 2015-12-29 00:30:50 
    1 2015-12-28 23:59:12 
    2 NaT 
    3 NaT 
    4 2015-12-28 23:59:12 
    
  2. 寻找到日期缺少使用pd.isnull()指数:

    >>>missing = pd.isnull(dates_df['date']).index 
    >>>missing 
    Int64Index([2, 3], dtype='int64') 
    
  3. 要设置2日期间缺少日期为中点:

    start_date = dates_df.iloc[0,:] 
    end_date = dates_df.iloc[4,:] 
    missing_date = start_date + (end_date - start_date)/2 
    
3
import calendar 
import numpy as np 
import pandas as pd 

def tuple_to_timestamp(x): 
    try: 
     return calendar.timegm(x)    # 1 
    except (TypeError, ValueError): 
     return np.nan 

df = pd.DataFrame({'orig': [ 
    (2015, 12, 29, 0, 30, 50, 1, 363, 0), 
    (2015, 12, 28, 23, 59, 12, 0, 362, 0), 
    'None', '', 
    (2015, 12, 30, 23, 59, 12, 0, 362, 0)]}) 

ts = df['orig'].apply(tuple_to_timestamp)  # 2 
# 0 1451349050 
# 1 1451347152 
# 2   NaN 
# 3   NaN 
# 4 1451519952 
# Name: orig, dtype: float64 

ts = ts.interpolate()       # 3 
# 0 1451349050 
# 1 1451347152 
# 2 1451404752 
# 3 1451462352 
# 4 1451519952 
# Name: orig, dtype: float64 

df['fixed'] = pd.to_datetime(ts, unit='s')  # 4 

print(df) 

收益率为

        orig    fixed 
0 (2015, 12, 29, 0, 30, 50, 1, 363, 0) 2015-12-29 00:30:50 
1 (2015, 12, 28, 23, 59, 12, 0, 362, 0) 2015-12-28 23:59:12 
2         None 2015-12-29 15:59:12 
3          2015-12-30 07:59:12 
4 (2015, 12, 30, 23, 59, 12, 0, 362, 0) 2015-12-30 23:59:12 

说明

  1. calendar.timegm将每个时间元组到的时间戳。与 time.mktime不同,它将时间元组解释为UTC,而不是本地时间。

  2. apply对于每行df['orig']调用tuple_to_timestamp

  3. 有关时间戳的好处是,他们是数字,那么你就可以使用 数值方法如Series.interpolate填写的NaN与插值 值。请注意,两个NaN做而不是得到填充相同的插值;它们的值根据ts.index给出的位置线性插值。

  4. pd.to_datetime将时间戳转换为日期。