二、函数
1、常用的统计学函数
函数名称 描述说明 count() 统计某个非空值的数量 sum() 求和 mean() 求均值 median() 求中位数 std() 求标准差 min() 求最小值 max() 求最大值 abs() 求绝对值 prod() 求所有数值的乘积
# 创建一个示例 DataFrame data = {'A': [1, 2, 3, 4, 5],'B': [10, 20, 30, 40, 50],'C': [100, 200, 300, 400, 500] } df = pd.DataFrame(data)# 计算每列的均值 mean_values = df.mean() print(mean_values)# 计算每列的中位数 median_values = df.median() print(median_values)#计算每列的方差 var_values = df.var() print(var_values)# 计算每列的标准差 std_values = df.std() print(std_values)# 计算每列的最小值 min_values = df.min() print("最小值:") print(min_values)# 计算每列的最大值 max_values = df.max() print("最大值:") print(max_values)# 计算每列的总和 sum_values = df.sum() print(sum_values)# 计算每列的非空值数量 count_values = df.count() print(count_values)
2、重置索引
重置索引(reindex)可以更改原 DataFrame 的行标签或列标签,并使更改后的行、列标签与 DataFrame 中的数据逐一匹配。通过重置索引操作,您可以完成对现有数据的重新排序。如果重置的索引标签在原 DataFrame 中不存在,那么该标签对应的元素值将全部填充为 NaN。
2.1 reindex
reindex() 方法用于重新索引 DataFrame 或 Series 对象。重新索引意味着根据新的索引标签重新排列数据,并填充缺失值。如果重置的索引标签在原 DataFrame 中不存在,那么该标签对应的元素值将全部填充为 NaN。
语法:
DataFrame.reindex(labels=None, index=None, columns=None, axis=None, fill_value=nan, method=None, level=None, copy=True, limit=None, tolerance=None) Series.reindex(labels=None, index=None, method=None, copy=True, level=None, fill_value=nan, limit=None, tolerance=None)
参数
labels
或index
/columns
:新索引的标签。对于DataFrame,可以分别通过index
和columns
参数来重新索引行和列。axis
:{0 或 'index', 1 或 'columns'}, 默认值为0。指定操作的轴。0或'index'表示重新索引行,1或'columns'表示重新索引列。fill_value
:在重新索引时用于填充缺失值的值。默认为NaN。method
:{None, 'ffill', 'bfill', 'nearest', 'pad', 'backfill'}, 可选。用于填充缺失值的方法。例如,'ffill'表示向前填充,'bfill'表示向后填充。level
:如果轴是MultiIndex(多层索引),则通过级别名称或编号重新索引。copy
:是否返回新对象。如果为False,并且新索引与原索引相同,则返回原对象。limit
:向前或向后填充时填充的最大连续NaN值数。tolerance
:用于匹配索引值的公差。
import pandas as pd import numpy as np # 创建一个示例DataFrame df = pd.DataFrame({ 'A': [1, 2, 3], 'B': [4, 5, 6] }, index=['a', 'b', 'c']) # 重新索引行 new_index = ['a', 'd', 'c'] df_reindexed = df.reindex(index=new_index) print(df_reindexed) # 重新索引列 new_columns = ['A', 'C', 'B'] df_reindexed_columns = df.reindex(columns=new_columns) print(df_reindexed_columns)# 使用fill_value填充NaN df_filled = df.reindex(index=['a', 'd', 'c'], fill_value=0) print(df_filled) # 使用method参数进行填充 df_ffill = df.reindex(index=['a', 'd', 'c'], method='ffill') print(df_ffill)
2.2 reindex_like
reindex_like 方法用于将一个 DataFrame 或 Series 的索引重新排列,使其与另一个 DataFrame 或 Series 的索引相匹配。如果在重新索引的过程中,新的索引与原始索引不完全匹配,那么不匹配的位置将会被填充为 NaN 值。
语法:
DataFrame.reindex_like(other, method=None, copy=True, limit=None, tolerance=None)
参数:
other:
类型:DataFrame 或 Series。
描述:用于对齐索引和列的参考对象。
method:
类型:字符串,默认为 None。
描述:用于填充缺失值的方法。可选值包括 'ffill'(前向填充)、'bfill'(后向填充)等。
copy:
类型:布尔值,默认为 True。
描述:是否返回新的 DataFrame 或 Series。
limit:
类型:整数,默认为 None。
描述:指定连续填充的最大数量。
tolerance:
类型:标量或字典,默认为 None。
描述:指定重新索引时的容差。
import pandas as pd# 创建两个示例 DataFrame df1 = pd.DataFrame({'A': [1, 2, 3],'B': [4, 5, 6] }, index=['a', 'b', 'c'])df2 = pd.DataFrame({'A': [7, 8, 9],'B': [10, 11, 12] }, index=['b', 'c', 'd'])# 使用 reindex_like 对齐 df1 的行索引到 df2 # df1 的行索引被重新索引为 df2 的行索引,因此 df1 中不存在的行索引 'd' 对应的行填充了 NaN。 df1_reindexed = df1.reindex_like(df2) print(df1_reindexed)
3、遍历
对于 Series 而言,您可以把它当做一维数组进行遍历操作;而像 DataFrame 这种二维数据表结构,则类似于遍历 Python 字典
Series 可直接获取相应的 value,而 DataFrame 则会获取列标签
3.1 Series遍历
- 使用
for
循环遍历索引和值
你可以使用Python的for
循环来遍历Series
的索引和值。Series
对象支持直接迭代,默认情况下迭代的是其值。
import pandas as pd # 创建一个Series对象 s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd']) # 遍历值 for value in s: print(value) # 遍历索引和值(使用enumerate) for index, value in enumerate(s): # 注意:这里enumerate提供的是值的索引(0, 1, 2, ...),不是Series的索引 # 如果需要Series的索引,应该使用items()方法 print(f"Index (from enumerate): {index}, Value: {value}") # 遍历索引和值(使用items()) for index, value in s.items(): print(f"Index: {index}, Value: {value}")
3.2 DataFrame 遍历
- 使用
iterrows()
方法
iterrows()
方法返回一个迭代器,该迭代器生成(索引,Series)对,其中索引是行的索引,而Series是包含该行数据的Series对象。
import pandas as pd # 创建一个DataFrame对象 df = pd.DataFrame({ 'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9] }, index=['a', 'b', 'c']) # 使用iterrows()遍历DataFrame for index, row in df.iterrows(): print(f"Index: {index}") print(row) # row是一个Series对象,包含当前行的数据 print(row['A'], row['B'], row['C']) # 访问当前行的特定列
- 使用
itertuples()
方法
itertuples()
方法返回一个名为Pandas
的命名元组的迭代器,其索引是行的索引,而命名元组的字段名是列名。这个方法比iterrows()
更快,因为它返回的是轻量级的对象。
# 使用itertuples()遍历DataFrame for row in df.itertuples(index=True, name='Pandas'): print(f"Index: {row.Index}") # 注意这里的Index是大写的,因为它是命名元组的一个字段 print(row.A, row.B, row.C) # 直接通过列名访问数据
- 使用
apply()
方法
虽然apply()
方法不是直接用于遍历的,但它允许你将一个函数应用于DataFrame的行或列上。你可以指定axis
参数来决定函数是沿着行(axis=1
)还是列(axis=0
)应用的。
# 定义一个函数 def sum_row(row): return row.sum() # 对每一行应用函数 row_sums = df.apply(sum_row, axis=1) print(row_sums)
- 直接遍历列或行(不推荐用于大数据集)
虽然你可以直接遍历DataFrame的.columns
或.index
来访问列或行,但这通常不是最高效的方法,特别是对于大数据集。不过,在某些情况下,它可能是有用的。
# 遍历列 for column in df.columns: print(f"Column: {column}") print(df[column]) # 访问整列数据 # 遍历行(不推荐,因为这会创建DataFrame的副本) for _, row in df.iterrows(): # 注意:这里我们不使用_来存储索引,因为我们不关心它 # 但这样做会创建一个行的副本,这在大数据集上可能很慢 print(row)
3.3注意事项
- 当遍历大数据集时,
iterrows()
和直接遍历行可能会导致性能问题,因为它们每次迭代都会创建一个Series或DataFrame的副本。在这种情况下,优先考虑使用itertuples()
或向量化操作。apply()
方法通常比循环更快,特别是当你能够对整个列或行进行向量化操作时。- 对于简单的操作,如求和或计算平均值,直接使用Pandas的内置方法(如
sum()
、mean()
等)通常是最快的。
4、排序
4.1 sort_index
sort_index
方法会根据索引的值对 DataFrame 或 Series 进行排序。默认情况下,排序是升序的,但你也可以指定为降序。
语法:
DataFrame.sort_index(axis=0, ascending=True, inplace=False) Series.sort_index(axis=0, ascending=True, inplace=False)
参数:
ascending
:布尔值或布尔值列表,默认为 True,表示升序。如果设置为 False,则为降序。如果是列表,则可以对多级索引的每一级分别指定排序顺序。inplace
:布尔值,默认为 False。如果设置为 True,则直接在原对象上进行排序,不返回新的对象。kind
:字符串,指定排序算法,默认为 'quicksort'。其他选项包括 'mergesort' 和 'heapsort'。不同的算法在性能和稳定性方面有所不同。level
:如果索引是多级索引(MultiIndex),可以通过这个参数指定对哪一级进行排序。sort_remaining
:布尔值,默认为 True。如果索引是多级索引,并且只指定了level
参数对某一级进行排序,这个参数决定是否对剩下的级别也进行排序。by
:在 DataFrame 的上下文中,这个参数允许你指定一个或多个列名,按照这些列的值进行排序,而不是按照索引排序。虽然这与sort_index
的直接目的不符,但在某些情况下可能会用到。
import pandas as pd# 创建一个示例 DataFrame data = {'A': [1, 2, 3],'B': [4, 5, 6],'C': [7, 8, 9] } df = pd.DataFrame(data, index=['b', 'c', 'a'])# 按行索引排序 df_sorted = df.sort_index()print(df_sorted)
4.2 sort_values
sort_values
方法允许你指定一个或多个列名,按照这些列的值对 DataFrame 进行排序。你可以对单列进行排序,也可以对多列进行层级排序(即先按一列排序,如果这一列中有相同的值,则再按另一列排序,依此类推)。
语法:
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
参数
by
:字符串或字符串列表,指定要排序的列名。axis
:{0 或 'index', 1 或 'columns'},默认为 0。0 或 'index' 表示对行进行排序(沿着列的方向),1 或 'columns' 表示对列进行排序(沿着行的方向)。ascending
:布尔值或布尔值列表,默认为 True。如果为 True,则进行升序排序;如果为 False,则进行降序排序。如果是列表,则可以对多列分别指定排序顺序。inplace
:布尔值,默认为 False。如果为 True,则直接在原对象上进行排序,不返回新的对象。kind
:字符串,指定排序算法,默认为 'quicksort'。其他选项包括 'mergesort' 和 'heapsort'。不同的算法在性能和稳定性方面有所不同。na_position
:{'first', 'last'},默认为 'last'。指定缺失值(NaN)在排序后的位置。ignore_index
:布尔值,默认为 False。如果为 True,则结果中的索引将被重置为默认整数索引。key
:函数,用于在排序之前对每个元素进行转换。这通常用于复杂排序,比如对字符串长度进行排序。
import pandas as pd# 创建一个示例 DataFrame data = {'A': [3, 2, 1],'B': [6, 5, 4],'C': [9, 8, 7] } df = pd.DataFrame(data, index=['b', 'c', 'a'])# 按列 'A' 排序 df_sorted = df.sort_values(by='A') print(df_sorted)# 按列 'A' 和 'B' 排序 df_sorted = df.sort_values(by=['A', 'B']) print(df_sorted)# 按列 'A' 降序排序 df_sorted = df.sort_values(by='A', ascending=False) print(df_sorted)
5、去重
在 pandas 中,去重是一个常见的操作,尤其是在处理包含重复数据的 DataFrame 或 Series 时。pandas 提供了多种方法来实现去重,以下是一些常用的方法:
5.1DataFrame 去重
对于 DataFrame,去重通常意味着删除具有完全相同行的数据(即所有列的值都相同)。你可以使用 drop_duplicates
方法来实现这一点。
import pandas as pd # 创建一个包含重复行的 DataFrame data = { 'Name': ['Alice', 'Bob', 'Alice', 'David'], 'Age': [24, 27, 24, 32], 'Score': [88, 92, 88, 85] } df = pd.DataFrame(data) # 使用 drop_duplicates 方法去重 df_unique = df.drop_duplicates() print(df_unique)#Name Age Score #0 Alice 24 88 #1 Bob 27 92 #3 David 32 85
Series 去重
对于 Series,去重意味着删除具有重复值的元素,并可能返回一个新的 Series,其中每个值只出现一次。你可以使用 drop_duplicates
方法(Series 和 DataFrame 共享这个方法)或 unique
方法来实现这一点。
# 创建一个包含重复值的 Series s = pd.Series(['Alice', 'Bob', 'Alice', 'David', 'Bob']) # 使用 drop_duplicates 方法去重(保留第一次出现的值) s_unique_drop = s.drop_duplicates() # 使用 unique 方法去重(返回一个包含所有唯一值的数组) s_unique_array = s.unique() # 将 unique 方法的结果转换回 Series s_unique = pd.Series(s_unique_array) print(s_unique_drop) print(s_unique)
参数
subset
:字符串或字符串列表,可选。指定要考虑哪些列(对于 DataFrame)或元素(对于 Series)进行去重。默认情况下,考虑所有列或元素。keep
:{'first', 'last', False},默认 'first'。指定在找到重复项时要保留哪个值。'first' 保留第一次出现的值,'last' 保留最后一次出现的值,False 不保留任何重复值(但这在 DataFrame 中通常没有意义,因为这会删除整行)。inplace
:布尔值,默认 False。如果为 True,则直接在原对象上进行去重,不返回新的对象。ignore_index
:布尔值,默认 False。如果为 True,则结果中的索引将被重置为默认整数索引(仅对 DataFrame 有效,因为 Series 总是具有整数索引)。
6、分组
6.1 groupby
groupby 方法用于对数据进行分组操作,这是数据分析中非常常见的一个步骤。通过 groupby,你可以将数据集按照某个列(或多个列)的值分组,然后对每个组应用聚合函数,比如求和、平均值、最大值等。
语法:
DataFrame.groupby(by, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)
参数:
by:用于分组的列名或列名列表。
axis:指定沿着哪个轴进行分组。默认为 0,表示按行分组。
level:用于分组的 MultiIndex 的级别。
as_index:布尔值,指定分组后索引是否保留。如果为 True,则分组列将成为结果的索引;如果为 False,则返回一个列包含分组信息的 DataFrame。
sort:布尔值,指定在分组操作中是否对数据进行排序。默认为 True。
group_keys:布尔值,指定是否在结果中添加组键。
squeeze:布尔值,如果为 True,并且分组结果返回一个元素,则返回该元素而不是单列 DataFrame。
observed:布尔值,如果为 True,则只考虑数据中出现的标签。
import pandas as pd# 创建一个示例 DataFramedata = {'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],'C': [1, 2, 3, 4, 5, 6, 7, 8],'D': [10, 20, 30, 40, 50, 60, 70, 80]}df = pd.DataFrame(data)# 按列 'A' 分组grouped = df.groupby('A')# 查看分组结果for name, group in grouped:print(f"Group: {name}")print(group)print()
6.2 filter
假设你有一个 DataFrame,已经使用 groupby
方法对其进行了分组,现在你想要根据每个组的某些条件来过滤这些组。你可以使用 filter
方法来实现这一点。
import pandas as pd # 创建一个 DataFrame df = pd.DataFrame({ 'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B': [1, 2, 3, 4, 5, 6, 7, 8], 'C': [2.0, 5.0, 8.0, 1.0, 2.0, 9.0, 8.0, 7.0] }) # 按列 'A' 分组 grouped = df.groupby('A') # 使用 filter 方法过滤组 # 例如,只保留那些列 'B' 的值的和大于 10 的组 filtered_df = grouped.filter(lambda x: (x['B'].sum() > 10)) print(filtered_df)
在这个例子中,
filter
方法接收一个函数作为参数,该函数接收一个 DataFrame(因为我们是按列 'A' 对整个 DataFrame 进行分组的),并返回一个布尔值序列。在这个函数内部,我们计算了每个组中列 'B' 的值的和,并检查这个和是否大于 10。如果大于 10,则filter
方法会保留该组中的所有行;否则,它会删除这些行。
7、合并
merge 函数用于将两个 DataFrame 对象根据一个或多个键进行合并,类似于 SQL 中的 JOIN 操作。这个方法非常适合用来基于某些共同字段将不同数据源的数据组合在一起,最后拼接成一个新的 DataFrame 数据表。
语法:
pandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
参数:
left
: 左侧 DataFrame 或 Series 对象。right
: 右侧 DataFrame 或 Series 对象。how
: 指定合并类型。默认为 'inner'。其他选项包括 'left', 'right', 'outer'。
- 'inner': 只返回两个对象中都存在的键的交集。
- 'left': 返回左对象的所有键,以及右对象中匹配的键。
- 'right': 返回右对象的所有键,以及左对象中匹配的键。
- 'outer': 返回左对象和右对象中所有键的并集。
on
: 要加入的列名。必须在左右对象中都存在。如果未指定且left_on
和right_on
也未指定,则 pandas 会尝试使用两个对象中列名的交集作为合并键。left_on
: 左对象中的列或索引级别名称用作键。可以是列名、索引级别的名称或数组形式的多个列名。right_on
: 右对象中的列或索引级别名称用作键。用法与left_on
相同。left_index
: 如果为 True,则使用左对象的索引(行标签)作为其合并键。对于多级索引,级别数必须匹配right_on
中的列数或right_index
中的级别数。right_index
: 如果为 True,则使用右对象的索引(行标签)作为其合并键。用法与left_index
相同。sort
: 根据合并键对合并后的数据进行排序。默认为 False。注意,如果合并键在合并后的数据中不是唯一的,则排序结果可能不稳定。suffixes
: 用于追加到重叠列名末尾的字符串元组。默认为 ('_x', '_y')。例如,如果两个对象都有名为 'A' 的列,则结果中的列名将分别为 'A_x' 和 'A_y'。copy
: 如果为 False,并且合并不需要重新分配内存(例如,在合并没有重叠列的情况下),则不会复制数据。默认为 True。indicator
: 如果为 True 或字符串,则向输出 DataFrame 添加一个特殊列 '_merge',以指示每行数据的来源:'left_only'、'right_only' 或 'both'。如果为字符串,则该字符串将用作列名。默认为 False。validate
: 检查合并键的有效性。可以是 'one_to_one', 'one_to_many', 'many_to_one', 'many_to_many' 中的一个。如果合并类型与指定的验证不匹配,则会引发 MergeError。默认为 None,不进行验证。
import pandas as pd # 创建两个 DataFrame df1 = pd.DataFrame({ 'key': ['K0', 'K1', 'K2', 'K3'], 'A': ['A0', 'A1', 'A2', 'A3'], 'B': ['B0', 'B1', 'B2', 'B3'] }) df2 = pd.DataFrame({ 'key': ['K0', 'K1', 'K2', 'K4'], 'C': ['C0', 'C1', 'C2', 'C4'], 'D': ['D0', 'D1', 'D2', 'D4'] }) # 使用 pandas.merge() 合并两个 DataFrame merged_df = pd.merge(df1, df2, on='key', how='inner') print(merged_df)
在这个例子中,我们根据 'key' 列将
df1
和df2
合并在一起,并指定了合并类型为 'inner'。结果merged_df
将包含两个 DataFrame 中都存在的 'key' 值的行。
8、时间
8.1 datetime
datetime 模块提供了用于处理日期和时间的类。
from datetime import datetimedt = datetime(2024, 5, 19, 16, 45, 30) print(dt) print(dt.date()) # 输出: 2024-05-19 print(dt.time()) # 输出: 16:45:30
8.2 Timestamp
Timestamp 是一个特殊的 datetime 类型,用于表示单个时间点。它是 pandas 时间序列功能的核心组件,提供了丰富的方法和属性来处理日期和时间数据。
import pandas as pd# 从日期字符串创建 ts = pd.Timestamp('2024-05-19 16:45:00') print(ts)# 从时间戳创建 ts = pd.Timestamp(1652937700) # Unix 时间戳 print(ts)
8.3 日期解析
pd.to_datetime() 方法用于将字符串或其他格式的日期转换为 Pandas 的 Datetime 对象。
import pandas as pd# 将字符串转换为 Datetime 对象 date_str = '2023-10-01' date_obj = pd.to_datetime(date_str) print(date_obj)# 获取当前时间 print('当前时间:') print(datetime.now())
8.4 date_range
date_range() 函数用于生成一个固定频率的日期时间索引(DatetimeIndex)。这个函数非常灵活,可以用于生成各种时间序列数据。
语法:
pandas.date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs)
参数:
start
: 字符串或datetime-like
,表示时间范围的开始。end
: 字符串或datetime-like
,表示时间范围的结束。periods
: 整数,表示要生成的时期(时间戳)数量。freq
: 字符串或DateOffset
,表示频率。例如,'D' 表示日,'H' 表示小时。tz
: 字符串或pytz.timezone
,表示时区。normalize
: 布尔值,如果为 True,则将所有时间戳都规范化为午夜(00:00:00)。name
: 字符串,为返回的DatetimeIndex
设置名称。closed
: 字符串,{'left', 'right'},表示区间是左闭右开('left')还是右闭左开('right')。这仅当periods
被指定时才有效。
import pandas as pd# 生成从 2023-01-01 到 2023-01-10 的每日日期时间索引 date_index = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D') print(date_index)# 生成从 2023-01-01 00:00:00 到 2023-01-01 23:00:00 的每小时日期时间索引 date_index = pd.date_range(start='2023-01-01', periods=24, freq='H') print(date_index)
注意事项:
- 如果同时指定了
start
、end
和periods
,则 pandas 会尝试生成一个满足所有这些条件的日期时间索引。但是,如果这三个参数不能精确匹配,可能会引发错误或产生意外的结果。- 频率
freq
可以是任何有效的 pandas 频率字符串(如 'D'、'H'、'T'、'S' 分别表示日、小时、分钟和秒),或者是DateOffset
对象。- 时区
tz
参数允许你指定一个时区,这对于处理跨时区的时间序列数据特别有用。
8.5 时间差
Timedelta 是一个用于表示时间间隔的对象。它可以表示两个时间点之间的差异,或者表示某个时间段的长度。Timedelta 对象可以用于时间序列分析、日期运算等场景。
创建
Timedelta
对象你可以通过多种方式创建
Timedelta
对象:
- 使用
pd.Timedelta
函数:
- 通过传递一个表示时间差的字符串来创建,例如
'2 days 3 hours'
。- 通过传递一个整数和一个单位来创建,例如
pd.Timedelta(days=2)
。- 可以混合使用不同的单位,例如
pd.Timedelta(days=1, hours=30, minutes=15)
。- 在
DataFrame
或Series
上进行日期时间减法:
- 如果你有一个包含日期时间的
DataFrame
或Series
,你可以通过减去两个日期时间列来直接生成Timedelta
对象。
Timedelta
的属性和方法
- 属性:
days
:返回时间差中的天数部分。seconds
:返回时间差中的秒数部分(不包括天数转换的秒数)。microseconds
:返回时间差中的微秒数部分。total_seconds()
:返回时间差的总秒数(包括天数转换的秒数)。- 方法:
to_pytimedelta()
:将Timedelta
对象转换为 Python 标准库中的datetime.timedelta
对象。- 算术运算:
Timedelta
对象支持加法、减法、乘法和除法运算,可以与另一个Timedelta
对象或数字(表示时间单位的倍数)进行运算。
import pandas as pd # 创建 Timedelta 对象 delta_1 = pd.Timedelta(days=2, hours=3) delta_2 = pd.Timedelta('1 day 4 hours 30 minutes') # 输出 Timedelta 对象 print(delta_1) # 输出: 2 days 03:00:00 print(delta_2) # 输出: 1 days 04:30:00 # 算术运算 delta_sum = delta_1 + delta_2 delta_diff = delta_1 - delta_2 delta_mul = delta_1 * 2 delta_div = delta_1 / pd.Timedelta(hours=3) print(delta_sum) # 输出: 3 days 07:30:00 print(delta_diff) # 输出: 0 days 20:30:00 print(delta_mul) # 输出: 4 days 06:00:00 print(delta_div) # 输出: 17.0(表示 17 个小时) # 在 DataFrame 上计算时间差 df = pd.DataFrame({ 'start_time': pd.to_datetime(['2023-01-01 08:00', '2023-01-02 09:30']), 'end_time': pd.to_datetime(['2023-01-01 12:00', '2023-01-02 14:00']) }) df['time_difference'] = df['end_time'] - df['start_time'] print(df)
8.6 时间日期格式化
strftime
方法接受一个格式字符串作为参数,该字符串包含了各种格式化代码,这些代码会被替换为日期和时间对象的相应值。
常用的格式化代码
%Y
:四位数的年份,例如 2023。%m
:两位数的月份(01 到 12)。%d
:两位数的日(01 到 31)。%H
:两位数的小时(00 到 23,24小时制)。%I
:两位数的小时(01 到 12,12小时制)。%p
:本地化的AM或PM。%M
:两位数的分钟(00 到 59)。%S
:两位数的秒(00 到 59)。%f
:微秒(000000 到 999999)。%a
:本地化的星期几缩写(例如 Mon, Tue)。%A
:本地化的星期几全称(例如 Monday, Tuesday)。%b
:本地化的月份缩写(例如 Jan, Feb)。%B
:本地化的月份全称(例如 January, February)。%c
:本地化的日期和时间(例如 Tue Aug 16 01:03:52 1988)。%d
:一个月中的第几天(01 到 31)。%j
:一年中的第几天(001 到 366)。%U
:一年中的第几周(00 到 53,星期天为一周的开始)。%w
:一个星期中的第几天(0 到 6,0 表示星期天)。%W
:一年中的第几周(00 到 53,星期一为一周的开始)。%x
:本地化的日期(例如 08/16/88)。%X
:本地化的时间(例如 01:03:52)。%Z
:时区名称(如果不存在则为空字符串)。%%
:一个百分号。
import datetime # 创建一个 datetime 对象 dt = datetime.datetime(2023, 10, 5, 14, 30, 45) # 使用 strftime 方法格式化日期和时间 formatted_date = dt.strftime("%Y-%m-%d %H:%M:%S") print(formatted_date) # 输出: 2023-10-05 14:30:45
注意事项:
- 格式化代码是区分大小写的。例如,
%m
表示月份,而%M
表示分钟。- 如果你的日期时间对象包含时区信息(例如
pytz.datetime
或pandas.Timestamp
与时区),则某些格式化代码(如%Z
)可能会显示时区名称。- 格式化字符串中的其他字符(如
-
、/
、:
和空格)将按原样输出。