【问题标题】:How to convert a column in a pandas dataframe to datatime?如何将熊猫数据框中的列转换为日期时间?
【发布时间】:2019-10-31 00:42:22
【问题描述】:

我有一个 csv 文档,下面是一个例子:

oci,citing,cited,creation,timespan,journal_sc,author_sc
0200100000236252421370109080537010700020300040001-020010000073609070863016304060103630305070563074902,"10.1002/pol.1985.170230401","10.1007/978-1-4613-3575-7_2",1985-04,P2Y,no,no

有 2 列,代表日期,我想将列类型从字符串更改为 datetime 格式。

creation列(字符串)为创建日期,除不指定外还可以三种形式表示:

  1. “yyyy-mm-dd”(例如“2019-09-20”)
  2. “yyyy-mm”(例如“2019-09”)
  3. “yyyy”(例如“2019”)

timespan(字符串):按照PnYnMnD的形式表示,其中P是表达式开头的文字值,nY是后面跟文字Y的年数, nM 是后跟文字 M 的月数,nD 是后跟文字 D 的天数,如果这些数字和相应的指示符等于 0,则它们中的任何一个都可能不存在. 减号可能会出现在P 之前,表示负持续时间。

我正在尝试使用pd.to_datetime() 函数将列类型从字符串更改为datetime 格式:

def do_process(f_path):
    global my_ocan

    my_ocan = pd.read_csv(f_path, names=['oci', 'citing', 'cited', 'creation', 'timespan', 'journal_sc', 'author_sc'], parse_dates = ['creation', 'timespan'])
    my_ocan['timespan'] = pd.to_datetime(my_ocan['timespan'], format='%Y%m%d', errors='ignore', yearfirst=True)
    my_ocan['creation'] = pd.to_datetime(my_ocan['creation'], format='%Y%m%d', errors='ignore', yearfirst=True)
    #print(my_ocan['citing'])
    print(my_ocan.info())

    return my_ocan

执行print(my_ocan.info()) 时,我得到'214 non-null object' 而不是datetime。我错过了什么?有什么问题?

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 214 entries, 0 to 213
Data columns (total 7 columns):
oci           214 non-null object
citing        214 non-null object
cited         214 non-null object
creation      214 non-null object
timespan      214 non-null object
journal_sc    214 non-null object
author_sc     214 non-null object
dtypes: object(7)

谢谢你们,祝你们有美好的一天:)

【问题讨论】:

  • 问题是“创作”列的多种输入。它尝试将其转换为 datetime 类型,但由于传入的值不同,它不能。它将其转换为对象。您可以将列转换回日期时间,但它会删除您的值。您可以使用 myocan.astype({'creation': 'datetime64[ns]'}).dtypes 之类的东西将其转换为日期时间类型。

标签: python python-3.x pandas datetime


【解决方案1】:

您的代码中有几个问题需要解决。

首先,请注意.csv 文件中的第一列是:

oci,citing,cited,creation,timespan,journal_sc,author_sc

因此,当您使用pd.read_csv 构建数据库时,数据框的第一行将是.csv 文件的第一行。你最终的数据框是:

                                                 oci  ...  author_sc
0                                                oci  ...  author_sc
1  0200100000236252421370109080537010700020300040...  ...         no

而不是:

[2 rows x 7 columns]
                                                 oci  ... author_sc
1  0200100000236252421370109080537010700020300040...  ...        no

我不认为你想要那个。

您还使用pd.to_datetime 抑制错误,这不是很好。删除errors='ignore' 后,您会注意到转换为datetime 失败,因为输入与'%Y%m%d' 格式不匹配。

当然不是,因为您的 creation 列是:

0    creation
1     1985-04

第一行是"creation",与'%Y%m%d'不匹配。

其次,日期格式应为'%Y-%m-%d',因为日期格式为 YYYY-MM-DD 而不是 YYYYMMDD。 (小心,因为例如,当您的格式中有天而输入没有时,日期会添加一天)。

第三,timespan 值不是日期,它们是句点(如果我没记错的话,是 Java 句点),所以在它们上使用 pd.to_datetime 是行不通的。我还没有找到一个可以为你进行转换的 python 函数,所以你可能不得不以一种很好的旧字符串解析方式自己完成这项工作,或者深入研究 python 库。

第四,正如documentation 所说,pd.to_datetime 已被弃用,因此您最好远离并使用例如 datetime.strptime,它的作用非常相似。

最后,这是您的代码的工作版本:

 def do_process(f_path):
     global my_ocan

     my_ocan = pd.read_csv(f_path, names=['oci', 'citing', 'cited', 'creation', 'timespan', 'journal_sc', 'author_sc'], parse_dates = ['creation', 'timespan'])
     my_ocan = my_ocan.iloc[1:]  # to remove the first row
     my_ocan['creation'] = pd.to_datetime(my_ocan['creation'], format="%Y-%m-%d", yearfirst=True)
     # Period parsing on my_ocan['timespan']
     print(my_ocan.info())

     return my_ocan

哪些输出:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1 entries, 1 to 1
Data columns (total 7 columns):
oci           1 non-null object
citing        1 non-null object
cited         1 non-null object
creation      1 non-null datetime64[ns]
timespan      1 non-null object
journal_sc    1 non-null object
author_sc     1 non-null object
dtypes: datetime64[ns](1), object(6)

Notice creation 现在是 datetime64[ns] 类型。

【讨论】:

  • 克里斯,非常感谢您的详细解释,并将我的想法引导到正确的轨道上! :)
猜你喜欢
  • 1970-01-01
  • 2019-05-22
  • 2019-01-24
  • 2019-02-17
  • 2020-03-14
  • 2018-12-08
  • 1970-01-01
相关资源
最近更新 更多