2015-12-31 76 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將時間戳轉換爲日期。