1.读取字符串日期

写入csv 文件

    csv_text = """date, value
2022-01-01, 1
2022-01-05, 5
2022-11-05, 5
"""
with open("date_text.csv", "w") as f:
    f.write(csv_text)

读取日期

df = pd.read_csv("date_text.csv")
print(df)
print(df.dtypes)

输出

         date   value
0  2022-01-01       1
1  2022-01-05       5
2  2022-11-05       5
date      object
 value     int64
dtype: object

上面的结果中,date列的类型被读作object类型,而不是一个datetime类型
一个简单的方式是让pandas解析日期,传入参数parse_date给read_csv方法,会得到datetime对象的date列:

df = pd.read_csv("date_text.csv", parse_dates=["date"])
print(df)
print(df.dtypes)

输出

        date   value
0 2022-01-01       1
1 2022-01-05       5
2 2022-11-05       5
date      datetime64[ns]
 value             int64
dtype: object

pandas中融合了很强大的日期解析方法,许多类型的日期都可以自动解析

有时候数据格式是这样的:

csv_text = """y,m,d,value
2022,01,02, 2
2022,01,03, 3
2022,11,05, 5
"""
with open("date_text.csv", "w") as f:
    f.write(csv_text)

读取日期的方式

df = pd.read_csv("date_text.csv", parse_dates={"date": ["y", "m", "d"]})
print(df)

为了从多列中解析出一个日期列,只需要给parse_dates参数传入一个字典对象指定要解析的列即可

2.指定日期格式

对于日期01/11/2022,格式可以理解为mm/dd/yyyy解析得到2022-01-11,也可以理解为dd/mm/yyyy解析得2022-11-01,是存在这样的不同的使用格式的,要明确格式,可以指定dayfirst参数:
写入csv文件

csv_text = """date,value
01/02/2022, 2
01/03/2022, 3
11/05/2022, 5
"""
with open("date_text.csv", "w") as f:
    f.write(csv_text)

读取数据

df = pd.read_csv("date_text.csv", parse_dates=["date"], dayfirst=True)
print(df)
df = pd.read_csv("date_text.csv", parse_dates=["date"], dayfirst=False)
print(df)

输出

        date  value
0 2022-02-01      2
1 2022-03-01      3
2 2022-05-11      5
        date  value
0 2022-01-02      2
1 2022-01-03      3
2 2022-11-05      5

除了使用dayfirst参数,也可以使用参数infer_datetime_format,将其设置为True,会自动推断默认的日期类型

指定date_parser来确定自定义的特殊的日期格式
假设输入的格式是这样的:

csv_text = """date,value
Jan_01_2022, 2
Jun_03_2022, 3
NOV_05_2022, 5
"""
with open("date_text.csv", "w") as f:
    f.write(csv_text)

使用infer_datetime_format参数是没办法推断出日期格式的

df = pd.read_csv("date_text.csv", parse_dates=["date"], infer_datetime_format=True)
print(df)

输出

              date  value
0      Jan_01_2022      2
1      Jun_03_2022      3
2      NOV_05_2022      5

此时可以指定date_parser来执行解析

from datetime import datetime
fmt = "%b_%d_%Y"
df = pd.read_csv("date_text.csv", parse_dates=["date"], date_parser=lambda x: datetime.strptime(x, fmt))
print(df)

输出

        date  value
0 2022-01-01      2
1 2022-06-03      3
2 2022-11-05      5

麻烦的是确定strptime的日期格式,不过你可以在这个网站上参考字符串日期解析成日期对象的格式

3.转换为datetime类型

可以使用pandas的to_datetime方法(参考pandas官网):

pandas.to_datetime(arg, errors=‘raise’, dayfirst=False,
yearfirst=False, utc=None, format=None, exact=True, unit=None,
infer_datetime_format=False, origin=‘unix’, cache=True)

dt = pd.to_datetime("01 Jan, 2022")
print(dt)
dt_li = pd.to_datetime(["01 Jan, 2022", "11/11/2022", "2222/12/12"])
print(dt_li)

to_datetime方法包含了绝大多数你需要执行的操作,而且arg既可以传入一个日期字符串参数也可以传入一个日期字符串列表

4.创建范围日期

使用pandas的date_range方法创建指定范围的日期
指定开始日期start和结束日期end创建范围类的日期

date_list = ["2021-11-01", "2021-11-05"]
date_range = pd.date_range(date_list[0], date_list[1])
print(date_range)

输出

DatetimeIndex(['2021-11-01', '2021-11-02', '2021-11-03', '2021-11-04',
               '2021-11-05'],
              dtype='datetime64[ns]', freq='D')

传入start日期或者end日期并传入period指定范围长度

start = "2021-11-01"
date_range1 = pd.date_range(start=start, periods=7)
print(date_range1)

end = "2021-11-01"
date_range2 = pd.date_range(end=end, periods=7)
print(date_range2)
DatetimeIndex(['2021-11-01', '2021-11-02', '2021-11-03', '2021-11-04',
               '2021-11-05', '2021-11-06', '2021-11-07'],
              dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2021-10-26', '2021-10-27', '2021-10-28', '2021-10-29',
               '2021-10-30', '2021-10-31', '2021-11-01'],
              dtype='datetime64[ns]', freq='D')

间隔类型指定为年(Y)、月(M)、时(H)等,指定timezone已经左右开闭

# 以月份为间隔
end = "2021-11-30"
month_range1 = pd.date_range(end=end, periods=3, freq='2M')     # freq也可以用pd.offsets.MonthEnd(2)
print(month_range1)

# tz指定时区
end = "2021-11-30"
month_range2 = pd.date_range(end=end, periods=3, freq='2H', tz="UTC+08:00")
print(month_range2)
# closed指定开闭区间,略
DatetimeIndex(['2021-07-31', '2021-09-30', '2021-11-30'], dtype='datetime64[ns]', freq='2M')
DatetimeIndex(['2021-11-29 20:00:00+08:00', '2021-11-29 22:00:00+08:00',
               '2021-11-30 00:00:00+08:00'],
              dtype='datetime64[ns, UTC+08:00]', freq='2H')
5.提取datetime对象的date,time等部分

使用pandas的dt accessor提取datetime对象中的各部分

start = "2021-11-02"
date_range1 = pd.date_range(start=start, periods=7, tz="UTC+08:00")
df = pd.DataFrame({"value": [i for i in range(7)], "date": date_range1})
# print(df)
df["date"], df["time"], df["tz"] = df["date"].dt.date, df["date"].dt.time, df["date"].dt.tz
print(df)
# (还可以提取weekday之类的!)
# print("weekday: \n", df["date"].dt.weekday)
   value        date      time         tz
0      0  2021-11-02  00:00:00  UTC+08:00
1      1  2021-11-03  00:00:00  UTC+08:00
2      2  2021-11-04  00:00:00  UTC+08:00
3      3  2021-11-05  00:00:00  UTC+08:00
4      4  2021-11-06  00:00:00  UTC+08:00
5      5  2021-11-07  00:00:00  UTC+08:00
6      6  2021-11-08  00:00:00  UTC+08:00
6.转换时区

生成utc+8时区的一个范围时间,然后使用tz_convert方法转换时区,使用strftime方法转换格式

# 指定时区偏移
tz_offset = 8
utc_ofst = 3600*tz_offset
# 生成指定时区的范围日期
end = "2021-11-30"
dates = pd.date_range(end=end, periods=3, tz=utc_ofst)
print(dates)
# 将日期时间转换为0时区时间,然后格式化成字符串
fmt = "%Y-%m-%d %H:%M:%S"
print([date.tz_convert(pytz.utc).strftime(fmt) for date in dates])
DatetimeIndex(['2021-11-28 00:00:00+08:00', '2021-11-29 00:00:00+08:00',
               '2021-11-30 00:00:00+08:00'],
              dtype='datetime64[ns, pytz.FixedOffset(480)]', freq='D')
['2021-11-27 16:00:00', '2021-11-28 16:00:00', '2021-11-29 16:00:00']
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐