【问题标题】:change date format in pandas更改熊猫中的日期格式
【发布时间】:2017-01-25 13:34:23
【问题描述】:

我有以下 csv 数据

country,sale,date,trans_factor
India,403171,12/01/2012,1
Bhutan,394096,12/01/2012,2
Nepal,super,12/01/2012,3
madhya,355883,12/01/2012,4
sudan,man,12/01/2012,5

csv_data = pandas.read_csv(csv_file_data, skiprows=[0], names=original_csv_header, parse_dates=True, infer_datetime_format=True)

print csv_data

  country    sale        date  trans_factor
0   India  403171  12/01/2012             1
1  Bhutan  394096  12/01/2012             2
2   Nepal   super  12/01/2012             3
3  madhya  355883  12/01/2012             4
4   sudan     man  12/01/2012             5

即使在添加parse_dates=True 之后,上面的代码也没有将值从12/01/2012 更改为2012-01-12,我不知道为什么

我想以'%d/%m/%Y' 格式格式化日期列,所以我尝试使用以下代码

dates = {
        'dd/mm/yy': "%d/%m/%Y",
        'mm/dd/yy': "%m/%d/%Y",
    }

def return_date_fromat(d, date_format):
    return datetime.datetime.strptime(d, date_format)


csv_data["date"] = csv_data["date"].apply(lambda d: return_date_fromat(d, dates['dd/mm/yy']))

基本上我使用 lambda 的另一个函数 return_date_fromat 因为当我像下面这样使用时

csv_data["date"] = csv_data["date"].apply(lambda d: datetime.datetime.strptime(d, dates['dd/mm/yy'])

我得到了*** NameError: global name 'dates' is not defined,因此我将函数return_date_fromat 用于lambda

那么最后如何格式化日期呢?

【问题讨论】:

    标签: python date pandas lambda


    【解决方案1】:

    我认为您需要将参数parse_dates 更改为[2],因为True 表示解析DatetimeIndex 参见docs

    解析日期 : 布尔值或整数或名称列表或列表或字典列表,默认为 False。

    如果为真 -> 尝试解析索引。
    如果 [1, 2, 3] -> 尝试将第 1、2、3 列分别解析为单独的日期列。
    如果 [[1, 3]] -> 合并第 1 列和第 3 列并解析为单个日期列。
    如果 {'foo' : [1, 3]} -> 将第 1、3 列解析为日期并调用结果'foo'。存在适用于 iso8601 格式日期的快速路径。

    import pandas as pd
    import numpy as np
    from pandas.compat import StringIO
    
    temp=u"""country,sale,date,trans_factor
    India,403171,12/01/2012,1
    Bhutan,394096,12/01/2012,2
    Nepal,super,12/01/2012,3
    madhya,355883,12/01/2012,4
    sudan,man,12/01/2012,5"""
    #after testing replace 'StringIO(temp)' to 'filename.csv'
    df = pd.read_csv(StringIO(temp), parse_dates=[2])
    #df = pd.read_csv(StringIO(temp), parse_dates=['date'])
    
    print (df)
      country    sale       date  trans_factor
    0   India  403171 2012-12-01             1
    1  Bhutan  394096 2012-12-01             2
    2   Nepal   super 2012-12-01             3
    3  madhya  355883 2012-12-01             4
    4   sudan     man 2012-12-01             5
    
    print (df.dtypes)
    country                 object
    sale                    object
    date            datetime64[ns]
    trans_factor             int64
    dtype: object
    

    编辑:

    如果需要自定义解析器添加参数date_parser:

    parser = lambda x: pd.datetime.strptime(x, '%d/%m/%Y')
    df = pd.read_csv(StringIO(temp), parse_dates=[2], date_parser=parser)
    print (df)
      country    sale       date  trans_factor
    0   India  403171 2012-01-12             1
    1  Bhutan  394096 2012-01-12             2
    2   Nepal   super 2012-01-12             3
    3  madhya  355883 2012-01-12             4
    4   sudan     man 2012-01-12             5
    

    但也可以dayfirst=True:

    df = pd.read_csv(StringIO(temp), parse_dates=[2], dayfirst=True)
    print (df)
      country    sale       date  trans_factor
    0   India  403171 2012-01-12             1
    1  Bhutan  394096 2012-01-12             2
    2   Nepal   super 2012-01-12             3
    3  madhya  355883 2012-01-12             4
    4   sudan     man 2012-01-12             5
    

    【讨论】:

    • 基本上我是动态或随机获取日期列的顺序,所以我不能用parse_dates=[2]对其进行硬核,所以在读取csv后是否可以将其更改为%d/%m/%Y ?
    • 是否可以通过df = pd.read_csv(StringIO(temp), parse_dates=['date']) 之类的列名进行解析?
    • 不,就像我在上一篇文章中所说的那样,我有这个代码csv_data[foreign_key.table_column_name] = csv_data[foreign_key.table_column_name].apply( lambda d: return_date_fromat(d, dates[foreign_key.date_format])),我是动态获取的,所以我需要更改方法return_date_fromat本身的格式,如果你不这样做'不介意这可能吗?
    • 只有一种解决方案,但有点危险-df = pd.read_csv(StringIO(temp), parse_dates=[0,1,2,3])-如果某些整数值与dates相似,则会解析错误。 :(
    • 201201012000 这样的值将被错误地解析为daetimes :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-31
    • 2023-02-03
    • 2019-11-28
    • 1970-01-01
    • 2022-10-15
    • 2018-09-01
    相关资源
    最近更新 更多