【问题标题】:Python Change String(date) format of specific column in csv filePython更改csv文件中特定列的字符串(日期)格式
【发布时间】:2017-03-09 21:49:57
【问题描述】:

我正在尝试将我的 csv 文件中名为 date 的列的值转换为另一种格式,例如:

原始记录

transfer id,player id,player name,season,date
732058,1126,,12/13,Jul 1- 2012
581951,1126,,11/12,Jun 3- 2011
295000,1126,,09/10,Aug 12- 2009
98459,1126,,06/07,Nov 6- 2006
7267,1126,,03/04,Jul 2- 2003
...

我想得到类似的结果

transfer id,player id,player name,season,date
732058,1126,,12/13,2012-07-01
581951,1126,,11/12,2011-06-03
295000,1126,,09/10,2009-08-12
98459,1126,,06/07,2006-11-06
7267,1126,,03/04,2003-07-02
...

由于csv文件中存储的数据是字符串,所以我写了一个可以转换日期格式的方法:

import time

# convert date from original format to new format
def date_convert(_date,fmt_original,fmt_new):
    if date_validate(_date,fmt_original):
        timeArray=time.strptime(_date,fmt_original)
        return time.strftime(fmt_new,timeArray)
    else:
        return '0001-01-01'

def date_validate(_date,fmt_original):
    try:
        time.strptime(_date, fmt_original)
        return True
    except ValueError:
        return False

然后我尝试更改 csv 文件中的日期,并尝试使用pandas,正如@MaxU 所说:

我写了一个类似的代码

import pandas as pd
import date_format

df=pd.read_csv('the_transfer_info_test.csv',delimiter=',')
df.date=date_format.date_convert(df.date, '%b %d- %Y', '%Y-%m-%d')
print df

一开始我遇到了这样的异常:

TypeError: expected string or buffer

我认为可能与数据类型有关,因为df.date在pandas中得到了一种Series,所以我编码为

df.date=date_format.date_convert(str(df.date), '%b %d- %Y', '%Y-%m-%d')

但它返回所有0001-01-01,这是 date_format 中的异常日期,因此我搜索了如何将系列转换为字符串并找到类似的答案 @Amit,我尝试了以下方法:

df['date'].astype(basestring)
df.date.apply(str)
df['date'].astype(str)
df['date'].astype('str')

但它们对我不起作用,我遇到了同样的异常,例如:

TypeError: expected string or buffer

我想知道如何转换 csv 文件中的特定列值,无论是否使用 pandas。

顺便说一句,我的 python 版本是 2.7.12,带有 IDE PyCharm 和 Anoconda 4.0.0 和 pandas 0.18.0。

感谢任何帮助,谢谢。


感谢@jezrael,因为我上面的示例都运行良好,这是我的错,我的意思是简化我的问题并简化我的问题,实际上我的原始数据是这样的:

transfer id,player id,player name,season,date,move from,move from id,move to,move to id,market value,transfer fee
732058,1126,,12/13,Jul 1- 2012,e-frankfurt,24,1-fc-koln,3,£1.06m,Free transfer
581951,1126,,11/12,Jul 1- 2011,fc-st-pauli,35,eintracht-frankfurt,24,£1.70m,£425k
295000,1126,,09/10,Jul 1- 2009,alem-aachen,8,fc-st-pauli,35,£850k,Free transfer
98459,1126,,06/07,Jul 1- 2006,1860-munich,72,alemannia-aachen,8,£1.36m,£765k
7267,1126,,03/04,Jul 1- 2003,stuttgart-ii,102,tsv-1860-munich,72,-,£21k
...

实际上这些方法适用于 我的部分数据 我的意思是,如果我用几行相同格式的行来测试它,但是当涉及到大约 40000 条记录的原始数据时,它是有线表示这些方法不再起作用,对于to_datetime 方法,我遇到了一个异常,例如

ValueError: time data '-' does not match format '%b %d- %Y' (match)

虽然使用第二种方法为parse_dates,但日期格式与Jun 11- 2016 保持相同。

再次感谢任何帮助。

【问题讨论】:

    标签: python date csv pandas format


    【解决方案1】:

    我觉得你需要to_datetime:

    df.date = pd.to_datetime(df.date, format='%b %d- %Y')
    print (df)
       transfer id  player id  player name season       date
    0       732058       1126          NaN  12/13 2012-07-01
    1       581951       1126          NaN  11/12 2011-06-03
    2       295000       1126          NaN  09/10 2009-08-12
    3        98459       1126          NaN  06/07 2006-11-06
    4         7267       1126          NaN  03/04 2003-07-02
    

    但您似乎可以在read_csv 中使用参数parse_dates

    import pandas as pd
    from pandas.compat import StringIO
    
    temp=u"""transfer id,player id,player name,season,date
    732058,1126,,12/13,Jul 1- 2012
    581951,1126,,11/12,Jun 3- 2011
    295000,1126,,09/10,Aug 12- 2009
    98459,1126,,06/07,Nov 6- 2006
    7267,1126,,03/04,Jul 2- 2003
    """
    #after testing replace StringIO(temp) to filename
    df = pd.read_csv(StringIO(temp), parse_dates=['date'])
    
    print (df)
       transfer id  player id  player name season       date
    0       732058       1126          NaN  12/13 2012-07-01
    1       581951       1126          NaN  11/12 2011-06-03
    2       295000       1126          NaN  09/10 2009-08-12
    3        98459       1126          NaN  06/07 2006-11-06
    4         7267       1126          NaN  03/04 2003-07-02
    

    通过评论编辑:

    您需要参数errors='coerce' 来替换坏数据(格式无法匹配NaT):

    df.date = pd.to_datetime(df.date, format='%b %d- %Y', errors='coerce')
    
    print (df)
       transfer id  player id  player name season         date     move from  \
    0       732058       1126          NaN  12/13  Jul 1- 2012   e-frankfurt   
    1       581951       1126          NaN  11/12  Jul 1- 2011   fc-st-pauli   
    2       295000       1126          NaN  09/10  Jul 1- 2009   alem-aachen   
    3        98459       1126          NaN  06/07  Jul 1- 2006   1860-munich   
    4         7267       1126          NaN  03/04  Jul 1- 2003  stuttgart-ii   
    5         7267       1126          NaN  03/04            -  stuttgart-ii   
    
       move from id              move to  move to id market value   transfer fee  
    0            24            1-fc-koln           3       £1.06m  Free transfer  
    1            35  eintracht-frankfurt          24       £1.70m          £425k  
    2             8          fc-st-pauli          35        £850k  Free transfer  
    3            72     alemannia-aachen           8       £1.36m          £765k  
    4           102      tsv-1860-munich          72            -           £21k  
    5           102      tsv-1860-munich          72            -           £21k 
    
    df.date = pd.to_datetime(df.date, format='%b %d- %Y', errors='coerce')
    print (df)
       transfer id  player id  player name season       date     move from  \
    0       732058       1126          NaN  12/13 2012-07-01   e-frankfurt   
    1       581951       1126          NaN  11/12 2011-07-01   fc-st-pauli   
    2       295000       1126          NaN  09/10 2009-07-01   alem-aachen   
    3        98459       1126          NaN  06/07 2006-07-01   1860-munich   
    4         7267       1126          NaN  03/04 2003-07-01  stuttgart-ii   
    5         7267       1126          NaN  03/04        NaT  stuttgart-ii   
    
       move from id              move to  move to id market value   transfer fee  
    0            24            1-fc-koln           3       £1.06m  Free transfer  
    1            35  eintracht-frankfurt          24       £1.70m          £425k  
    2             8          fc-st-pauli          35        £850k  Free transfer  
    3            72     alemannia-aachen           8       £1.36m          £765k  
    4           102      tsv-1860-munich          72            -           £21k  
    5           102      tsv-1860-munich          72            -           £21k  
    

    【讨论】:

    • 感谢您的帮助,您的方法适用于样本记录,但对于较大的 csv 文件(如 40000 条记录 csv 文件)失败了,我已经更新了我的描述,很高兴您能提供进一步的帮助。
    • 我添加样本数据,检查样本的最后一行 - - 转换为 NaT
    • 是的,它工作得很好,谢谢,所以你的另一种方法(如parse_dates)失败的原因也是因为记录中的数据错误?
    • 再次感谢,我会探索熊猫,因为它对我来说很新
    猜你喜欢
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2011-05-04
    • 2018-05-22
    • 2022-07-04
    • 2023-03-18
    • 2021-12-16
    相关资源
    最近更新 更多