Python Pandas 时间数据处理与分析:读取、创建与时区转换

Python Pandas 时间数据处理与分析:读取、创建与时区转换

本文详细介绍了如何使用 pandas 处理和分析时间数据,包括时间序列的读取与格式化、自定义时间序列的创建、时间运算、特定时间段的数据获取和时区转换。通过 pd.to_datetime()pd.date_range() 等方法,开发者可以轻松读取日志或文件中的时间数据,创建自定义时间序列,并对时间进行加减运算。此外,文章还展示了如何利用 tz_localize()tz_convert() 进行时区设置和转换,以便实现多时区数据的管理与分析。图表展示与代码示例直观易懂,适合数据分析的入门学习。

引入第三方库

import numpy as np
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import pytz

一 主要功能

pandas 处理时间序列的常用方法

功能描述方法1方法2方法3
读时间序列数据pd.to_datetime()--
自建时间序列pd.date_range()--
时间运算pd.Timedelta()dt.dayofyear; dt.dayofweekdt.weekofyear; dt.weekday
格式化时间dt.strftime()dt.day_name()dt.month_name()
时区tz_localize()tz_convert()pytz.country_timezones()

二 时序列数据读取

从日志文件或者其他文件中读取出的时间序列数据通常为 dtype: object。可以使用 pd.to_datetime() 将其转换为 datetime64 类型。

    # 创建示例数据框  
    df = pd.DataFrame({
        "time": ["2022/03/12", "2022/03/13", "2022/03/14"],
        "value": [1, 2, 3]
    })
    print(df)
    print("\n\ntime:\n", df["time"])

将时间列 dtype: object 转换为 datetime64

		# 将时间列从 dtype:object 转换为 datetime64 类型
		print(pd.to_datetime(df["time"]))
格式化字符串转换为日期格式

pd.to_datetime() 可以处理格式不统一的日期字符串,并通过 format 参数来指定复杂的自定义格式:

		# 转换多种格式的日期字符串
  	print(pd.to_datetime(
        ["2022/03/12", "2022.03.13", "14/03/2022"], format='mixed'))
    
    # 自定义格式转换
    print(pd.to_datetime(
        [
            "1@21@2022%%11|11|32",
            "12@01@2022%%44|02|2",
            "4@01@2022%%14|22|2"
        ],
        format="%m@%d@%Y%%%%%S|%H|%M"))

:时间格式化字符串 %m, %d, %Y, %%, %S, %H, %M 分别代表月、日、完整的年份、百分号%、秒、小时和分钟。可以随时查阅 Python 官方文档 以了解详细的用法。

三 自定义时间序列数据

可以使用 pd.date_range() 创建自定义时间序列数据

  	# 创建时间范围 	
  	start = datetime.datetime(2022, 3, 12)
    end = datetime.datetime(2022, 3, 18)

    index = pd.date_range(start, end)
    print(index)

Python 中 range() 可以控制步长,类似地,pandas 中的 pd.date_range() 也支持通过 freq 参数来控制时间间隔:

		# range 和 pd.date_range 示例
		print("range(1, 10, 2)\n", list(range(1, 10, 2)))
		print("\n\npd.date_range()\n", pd.date_range(start, end, freq="48h"))

Numpy 中 np.linspace() 可以在区间内均匀分割数据,类似地,pandas 中pd.date_range() 可以使用 periods 参数创建指定周期的数据:

		# np.linspace 和 pd.date_range 示例
		print("np.linspace(-1, 1, 5)\n", np.linspace(-1, 1, 5))
		print("\n\nPd.date_range with periods\n", pd.date_range(start, end, periods=5))

四 时间序列数据获取

 	 	# 创建时间序列数据  
  	start = datetime.datetime(2022, 3, 1)
    end = datetime.datetime(2022, 5, 3)

    rng = pd.date_range(start, end)
    ts = pd.Series(np.random.randn(len(rng)), index=rng)
    print(ts)
    print(ts.index)
    print(ts.plot())
    plt.show()

在这里插入图片描述

时间分片可以用于获取特定时间段的数据,例如获取一周内的数据:

    # 获取一周内的时间序列数据
    ts[1:8].plot()
    plt.show()

在这里插入图片描述

还可以通过指定时间范围获取时间片段:

  	# 获取特定时间范围的数据 	
  	t1 = datetime.datetime(2022, 3, 12)
    t2 = datetime.datetime(2022, 3, 18)
    # ts[t1: t2].plot()
    # plt.show()
    ts["2022-03-12": "2022-03-18"].plot()
    plt.show()

在这里插入图片描述

按月获取数据:

    # 获取特定月份的数据
    ts["2022-03"].plot()
    plt.show()

在这里插入图片描述

五 时间运算

时间序列数据支持时间运算,可以加减时间段(pd.Timedelta()):

  	# 时间运算示例  
  	rng = pd.date_range("2022-01-01", "2022-01-07")
    print(rng + pd.Timedelta(weeks=1))
    print(rng + 2 * pd.Timedelta(days=3))
    
    rng = pd.date_range("2022-01-08", "2022-01-11")
    print(rng.dayofyear)
		# 格式化时间输出
    print(rng.strftime("%m/%d/%Y"))

更多参考:pandas Timestamp 文档

六 时区处理

处理时间序列数据时,可以使用 tz_localize()tz_convert() 进行时区设置和转换:

		# 时区处理示例
		rng = pd.date_range("2022-01-08", "2022-01-11")
		print(rng.tz is None)

		# 将时间序列数据本地化为特定时区
		s = pd.to_datetime(["2022/03/12 22:11", "2022/03/12 12:11", "2022/03/12 2:11"])
		s_us = s.tz_localize("America/New_York")
		print(s_us)

		# 转换到其他时区
		s_cn = s_us.tz_convert("Asia/Shanghai")
		print(s_cn)

		# 查看中国的所有时区
		print(pytz.country_timezones('CN'))

		# 创建包含时区的时间序列
		rng = pd.date_range("2022-01-08", "2022-01-11", tz="America/New_York")
		print(rng)

更多参考:pandas timeseries 文档

七 完整代码示例

# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import numpy as np
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import pytz


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press ⌘F8 to toggle the breakpoint.

    # 读时间序列数据

    df = pd.DataFrame({
        "time": ["2022/03/12", "2022/03/13", "2022/03/14"],
        "value": [1, 2, 3]
    })
    print(df)
    print("\n\ntime:\n", df["time"])
    # dtype:object
    # 转成 datetime64
    print(pd.to_datetime(df["time"]))
    print(pd.to_datetime(
        ["2022/03/12", "2022.03.13", "14/03/2022"], format='mixed'))
    print(pd.to_datetime(
        [
            "1@21@2022%%11|11|32",
            "12@01@2022%%44|02|2",
            "4@01@2022%%14|22|2"
        ],
        format="%m@%d@%Y%%%%%S|%H|%M"))
    # https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
    # %m 月
    # %d 日
    # %Y 年的全称
    # %% 比配一个 %
    # %S 秒
    # %H 时
    # %M 分

    # 自建时间序列
    start = datetime.datetime(2022, 3, 12)
    end = datetime.datetime(2022, 3, 18)

    index = pd.date_range(start, end)
    print(index)

    print(
        "range(1, 10, 2)\n",
        list(range(1, 10, 2))
    )
    print(
        "\n\npd.date_range()\n",
        pd.date_range(start, end, freq="48h")
    )
    print(
        "np.linspace(-1, 1, 5)\n",
        np.linspace(-1, 1, 5)
    )
    # 均匀分布
    print(
        "\n\npd.date_range(start, end, periods=5)\n",
        pd.date_range(start, end, periods=5)
    )
    # 选取时间
    start = datetime.datetime(2022, 3, 1)
    end = datetime.datetime(2022, 5, 3)

    rng = pd.date_range(start, end)
    ts = pd.Series(np.random.randn(len(rng)), index=rng)
    print()
    print(ts)
    print()
    print(ts.index)
    print(ts.plot())
    plt.show()
    # 显示某一周时间数据
    ts[1:8].plot()
    plt.show()
    # 时间本身分片
    t1 = datetime.datetime(2022, 3, 12)
    t2 = datetime.datetime(2022, 3, 18)
    ts[t1: t2].plot()
    plt.show()
    ts["2022-03-12": "2022-03-18"].plot()
    plt.show()
    # 按月按年取
    ts["2022-03"].plot()
    plt.show()
    print()
    # 时间运算
    # 加一周
    rng = pd.date_range("2022-01-01", "2022-01-07")
    print(rng + pd.Timedelta(weeks=1))
    print(rng + 2 * pd.Timedelta(days=3))
    rng = pd.date_range("2022-04-08", "2022-04-11")
    print(rng.dayofyear)

    print(rng.strftime("%m/%d/%Y"))
    # https://pandas.pydata.org/docs/reference/arrays.html#datetime-data

    # 时区
    rng = pd.date_range("2022-01-08", "2022-01-11")
    print(rng.tz is None)
    s = pd.to_datetime(
        ["2022/03/12 22:11", "2022/03/12 12:11", "2022/03/12 2:11"]
    )
    s_us = s.tz_localize("America/New_York")
    print(s_us)
    s_cn = s_us.tz_convert("Asia/Shanghai")
    print(s_cn)
    print(pytz.country_timezones('CN'))
    rng = pd.date_range(
        "2022-01-08", "2022-01-11",
        tz="America/New_York")
    print(rng)
    # https://pandas.pydata.org/docs/user_guide/timeseries.html


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    print_hi('时间数据')

# See PyCharm help at https://www.jetbrains.com/help/pycharm/

复制粘贴并覆盖到你的 main.py 中运行,运行结果如下。

Hi, 时间数据
         time  value
0  2022/03/12      1
1  2022/03/13      2
2  2022/03/14      3


time:
 0    2022/03/12
1    2022/03/13
2    2022/03/14
Name: time, dtype: object
0   2022-03-12
1   2022-03-13
2   2022-03-14
Name: time, dtype: datetime64[ns]
DatetimeIndex(['2022-03-12', '2022-03-13', '2022-03-14'], dtype='datetime64[ns]', freq=None)
DatetimeIndex(['2022-01-21 11:32:11', '2022-12-01 02:02:44',
               '2022-04-01 22:02:14'],
              dtype='datetime64[ns]', freq=None)
DatetimeIndex(['2022-03-12', '2022-03-13', '2022-03-14', '2022-03-15',
               '2022-03-16', '2022-03-17', '2022-03-18'],
              dtype='datetime64[ns]', freq='D')
range(1, 10, 2)
 [1, 3, 5, 7, 9]


pd.date_range()
 DatetimeIndex(['2022-03-12', '2022-03-14', '2022-03-16', '2022-03-18'], dtype='datetime64[ns]', freq='48h')
np.linspace(-1, 1, 5)
 [-1.  -0.5  0.   0.5  1. ]


pd.date_range(start, end, periods=5)
 DatetimeIndex(['2022-03-12 00:00:00', '2022-03-13 12:00:00',
               '2022-03-15 00:00:00', '2022-03-16 12:00:00',
               '2022-03-18 00:00:00'],
              dtype='datetime64[ns]', freq=None)

2022-03-01    1.481681
2022-03-02   -0.702829
2022-03-03    1.056303
2022-03-04   -0.466668
2022-03-05    1.025660
                ...   
2022-04-29   -0.546073
2022-04-30    0.621919
2022-05-01   -3.192217
2022-05-02    1.493657
2022-05-03    1.082105
Freq: D, Length: 64, dtype: float64

DatetimeIndex(['2022-03-01', '2022-03-02', '2022-03-03', '2022-03-04',
               '2022-03-05', '2022-03-06', '2022-03-07', '2022-03-08',
               '2022-03-09', '2022-03-10', '2022-03-11', '2022-03-12',
               '2022-03-13', '2022-03-14', '2022-03-15', '2022-03-16',
               '2022-03-17', '2022-03-18', '2022-03-19', '2022-03-20',
               '2022-03-21', '2022-03-22', '2022-03-23', '2022-03-24',
               '2022-03-25', '2022-03-26', '2022-03-27', '2022-03-28',
               '2022-03-29', '2022-03-30', '2022-03-31', '2022-04-01',
               '2022-04-02', '2022-04-03', '2022-04-04', '2022-04-05',
               '2022-04-06', '2022-04-07', '2022-04-08', '2022-04-09',
               '2022-04-10', '2022-04-11', '2022-04-12', '2022-04-13',
               '2022-04-14', '2022-04-15', '2022-04-16', '2022-04-17',
               '2022-04-18', '2022-04-19', '2022-04-20', '2022-04-21',
               '2022-04-22', '2022-04-23', '2022-04-24', '2022-04-25',
               '2022-04-26', '2022-04-27', '2022-04-28', '2022-04-29',
               '2022-04-30', '2022-05-01', '2022-05-02', '2022-05-03'],
              dtype='datetime64[ns]', freq='D')
Axes(0.125,0.11;0.775x0.77)

DatetimeIndex(['2022-01-08', '2022-01-09', '2022-01-10', '2022-01-11',
               '2022-01-12', '2022-01-13', '2022-01-14'],
              dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2022-01-07', '2022-01-08', '2022-01-09', '2022-01-10',
               '2022-01-11', '2022-01-12', '2022-01-13'],
              dtype='datetime64[ns]', freq='D')
Index([98, 99, 100, 101], dtype='int32')
Index(['04/08/2022', '04/09/2022', '04/10/2022', '04/11/2022'], dtype='object')
True
DatetimeIndex(['2022-03-12 22:11:00-05:00', '2022-03-12 12:11:00-05:00',
               '2022-03-12 02:11:00-05:00'],
              dtype='datetime64[ns, America/New_York]', freq=None)
DatetimeIndex(['2022-03-13 11:11:00+08:00', '2022-03-13 01:11:00+08:00',
               '2022-03-12 15:11:00+08:00'],
              dtype='datetime64[ns, Asia/Shanghai]', freq=None)
['Asia/Shanghai', 'Asia/Urumqi']
DatetimeIndex(['2022-01-08 00:00:00-05:00', '2022-01-09 00:00:00-05:00',
               '2022-01-10 00:00:00-05:00', '2022-01-11 00:00:00-05:00'],
              dtype='datetime64[ns, America/New_York]', freq='D')

八 源码地址

代码地址:

国内看 Giteepandas/时间数据.py

国外看 GitHubpandas/时间数据.py

引用 莫烦 Python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敲代码不忘补水

感谢有你,让我的创作更有价值!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值