首页 > 解决方案 > 如何将熊猫数据框中的列转换为数据时间?

问题描述

我有一个 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是年数,后面是文字YnM是月数,后面是文字MnD是天数,后面是一个文字D,如果这些数字和相应的指示符等于 0,则它们中的任何一个都可能不存在。减号可能出现在 之前P,表示负持续时间。

我正在尝试使用函数将列类型从字符串更改为datetime格式:pd.to_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)

谢谢你们,你们度过了美好的一天:)

标签: pythonpython-3.xpandasdatetime

解决方案


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

首先,请注意在您的.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"which doesn't match '%Y%m%d'

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

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

第四,正如文档所说,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)

通知现在creation是类型datetime64[ns]


推荐阅读