Pandas:通过二维字典映射现有Series创建新Series
解决二维字典映射生成新Series的问题
嘿,我来帮你搞定这个用二维字典给DataFrame生成新Series的需求!你要做的是根据datetime列,先匹配日期(字典的一级键),再匹配小时(对应日期子字典的键),最终生成新的dh列对吧?下面给你两种实用的方法,按需选择:
方法一:拆分datetime后逐行匹配(直观易懂)
这种方法先把datetime拆成日期字符串和小时数两个辅助字段,再通过apply逐行查找二维字典里的值,逻辑非常清晰,适合数据量不大的场景:
import pandas as pd # 先准备示例数据和二维映射字典 df = pd.DataFrame({ 'timestamp': pd.to_datetime(['2023-10-01 03:00', '2023-10-01 09:00', '2023-10-02 02:00']) }) hour_map = { '2023-10-01': {0: 'night', 1: 'night', 2: 'night', 3: 'night', 4: 'night', 5: 'dawn', 6: 'dawn', 7: 'morning', 8: 'morning', 9: 'morning'}, '2023-10-02': {0: 'late_night', 1: 'late_night', 2: 'late_night', 3: 'dawn', 4: 'dawn', 5: 'dawn', 6: 'morning', 7: 'morning', 8: 'morning'} } # 提取日期字符串和小时数 df['date_str'] = df['timestamp'].dt.strftime('%Y-%m-%d') df['hour'] = df['timestamp'].dt.hour # 生成dh列:先找日期对应的子字典,再匹配小时的值 df['dh'] = df.apply(lambda row: hour_map[row['date_str']][row['hour']], axis=1) # 不需要辅助列的话可以删掉 df = df.drop(['date_str', 'hour'], axis=1)
如果担心有缺失的(date, hour)组合会报错,可以用get方法设置默认值,把apply那行改成:
df['dh'] = df.apply(lambda row: hour_map[row['date_str']].get(row['hour'], 'unknown'), axis=1)
方法二:扁平化字典后向量化映射(高效适合大数据)
如果你的数据集很大,apply的逐行处理速度会比较慢,这时候可以把二维字典扁平化成元组键的一维字典,然后用向量化的map操作来匹配,速度会快很多:
# 把二维字典扁平化成 (日期字符串, 小时) 为键的字典 flat_map = {} for date, hour_subdict in hour_map.items(): for hour, value in hour_subdict.items(): flat_map[(date, hour)] = value # 生成(date_str, hour)元组的Series,然后直接映射 df['dh'] = list(zip(df['timestamp'].dt.date.astype(str), df['timestamp'].dt.hour)).map(flat_map)
同样,要处理缺失值的话,可以用get方法:
df['dh'] = list(zip(df['timestamp'].dt.date.astype(str), df['timestamp'].dt.hour)).map(lambda x: flat_map.get(x, 'unknown'))
注意事项
- 确保datetime列的时区统一,如果有时区差异,先通过
dt.tz_convert转成一致的时区,避免日期字符串不匹配。 - 如果你的日期键是
datetime.date类型而不是字符串,那提取的时候直接用df['timestamp'].dt.date即可,不用转字符串。
内容的提问来源于stack exchange,提问作者elPastor
相关产品推荐
相关产品推荐

