如何解析熊猫中不规则的日期格式?

时间:2019-07-24 22:17:02

标签: python pandas date

我正在解析一个日期列,其中包含大熊猫不会解释的不规则日期格式。日期包括日期,月份和年份的不同语言以及不同的格式。日期条目通常还包括时间戳。 (奖金:用lambda / loops通过字符串/正则表达式将它们分开是最快的方法吗?)解决这数万个日期条目的最佳选择和工作流程是什么?

pandasdateutil.parser未知的条目。

示例包括:

19.8.2017, 21:23:32 
31/05/2015 19:41:56   
Saturday, 18. May  
11 - 15 July 2001 
2019/4/28 下午6:29:28 
1 JuneMay 2000    
19 aprile 2008 21:16:37 GMT+02:00 
Samstag, 15. Mai 2010 20:55:10   
So 23 Jun 2007 23:45 CEST                                       
28 August 1998                                                 
30 June 2001    
1 Ноябрь 2008 г. 18:46:59  
Sat Jun 18 2011 19:46:46 GMT+0200 (Romance Daylight Time) 
May-28-11 6:56:08 PM
Sat Jun 26 2010 21:55:54 GMT+0200 (West-Europa (zomertijd))
lunedì 5 maggio 2008 9.30.33 
  

“ ValueError :('未知字符串格式:','2000年6月1日')”

我意识到这可能是一项繁琐且不受欢迎的任务。幸运的是,当前日期对于我的项目而言不是必需的,因此可以不理会这些日期,但是最好采用解决方案。任何和所有答复表示赞赏,谢谢。

1 个答案:

答案 0 :(得分:1)

逐行,很多日期有效:

from bs4 import BeautifulSoup as bs
import requests
import pandas as pd

r = requests.get('https://powerhouse.net/forecast-prijzen-onbalans/')
soup = bs(r.content, 'lxml')
table = soup.select_one('#endex_nl_forecast table')
rows = []
headers = [i.text for i in table.select('th')]

for tr in table.select('tr')[1:]:
    rows.append([i.text if i.svg is None else i.svg['class'][2].split('-')[-1] for i in tr.select('td') ])

df = pd.DataFrame(rows, columns = headers)
print(df)

但是有很多事情:

  • 由于您的格式不规则,熊猫无法猜测2019年2月1日是2019年2月1日还是2019年1月2日,所以我不知道是否可以,
  • 您的某些示例无法转换为日期>>> pd.to_datetime('19.8.2017, 21:23:32') Timestamp('2017-08-19 21:23:32') :哪一年?
  • 有不同语言的月份和日期(4月似乎是意大利语,Samstag是德语)
  • 您的某些示例在没有括号内容的情况下有效:
Saturday, 18. May

请确保您不能将所有日期都包含在时间戳中,我将尝试创建一个新列,并在时间戳中正确地解析日期,而另一列另存为>>> pd.to_datetime('Sat Jun 18 2011 19:46:46 GMT+0200') # works Timestamp('2011-06-18 19:46:46-0200', tz='pytz.FixedOffset(-120)') >>> pd.to_datetime('Sat Jun 18 2011 19:46:46 GMT+0200 (Romance Daylight Time) ') # doesn't work. ... ValueError: ('Unknown string format:', 'Sat Jun 18 2011 19:46:46 GMT+0200 (Romance Daylight Time) ')

例如:

NaT

将变为:

date
02-01-2019
Saturday, 18. May

为此,我将删除初始列中的括号:

date               new date
02-01-2019         Timestamp('2019-01-02 00:00:00.00)
Saturday, 18. May  NaT

之后,您可以看到保留df2 = df.assign( date2=lambda x: x['date'].str.split('(')[0], new_date=lambda x: x['date2'].apply(lambda y: pd.to_datetime(y, errors='coerce'), axis='columns')) # apply the function row by row # This will work with python >= 3.6 值还剩下什么。

对于翻译,您可以尝试替换单词,但这会很长。

这确实很慢(由于NaT逐行),但是如果您的数据不一致,则不能直接在列上工作。

我希望它会有所帮助。