Pandas: 时间转换器独立工作,但在读取 csv 文件时不工作

Pandas: time converter works in isolation but not when reading csv file

我想读取 csv 文件并将 Excel 序列时间值转换为 YYYY-MM-DD 字符串。该文件如下所示:

A    B    start_date
0    yes  42736
1    no   42751
2    yes  43039

我想用作转换器的函数是:

def convert_excel_time(excel_time):  
    return (pd.to_datetime('1900-01-01') + pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")

我是这样使用它的:

data = pd.read_csv("data.csv",encoding = "ISO-8859-1",
                  converters={'start_date': convert_excel_time})

当函数独立使用时,我得到了正确的结果:

excel_time = 42736
In[1]: (pd.to_datetime('1900-01-01')+pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")
Out[1]: '2017-01-03'

但是,如果我在读取 csv 文件时将该函数用作转换器,则我所有的开始日期都是“1900-01-01”。我做错了什么?

默认情况下,python 倾向于将文件读取为字符串。它通常会这样做,除非您告诉它不这样做。我不是特别熟悉 pandas 如何做事,但这似乎就是这里发生的事情:当 pd.read_csv() 读取您的文件时,它将 start_date 列解释为字符串。

documentation for pd.to_timedelta() 说它应该可以很好地读取字符串。但是当你实际测试这个方法时,它似乎在这种特殊情况下不起作用。

>>> pd.to_timedelta(44, "day")
Timedelta('44 days 00:00:00')
>>> pd.to_timedelta("44", "day")
Timedelta('0 days 00:00:00.000000')

我怀疑当它将 str 列为有效参数时,它指的是 TimeDelta 的字符串表示,而不是 int-as-a-str。无论出于何种原因,它都不会引发错误,而只是 returns 一个 zero-value 。

因此,您只需要确保传递的是 int 而不是 str。最简单的方法就是在函数 convert_excel_time():

的开头投射 excel_time
def convert_excel_time(excel_time):  
    excel_time = int(excel_time)
    return (pd.to_datetime('1900-01-01') + pd.to_timedelta(excel_time,unit='day')).strftime("%Y-%m-%d")

当实际读取数据时,pandas 似乎提供了一种机制来避免这个问题:pd.read_csv()dtype kwarg 允许您指定每一列的预期类型(str 大概是默认值)。问题是,如果你给出一个 converters kwarg,它就会被应用,所以你必须自己处理转换。