如何基于Pandas按门店按日存储未接来电时间数组?
问题描述
需要处理存储日期、门店名称及当日未接来电时间的DataFrame,将其转换为日期为外层键,门店为内层键,对应值为该门店当日未接来电时间列表的嵌套字典。
DataFrame结构示例:
Date Store Time 9/3/2023 Location A (8005) 8:29:29 AM 9/3/2023 Location B (8004) 9:03:58 AM 9/3/2023 Location B (8004) 9:45:45 AM 9/3/2023 Location C (8003) 9:50:29 AM 9/3/2023 Location D (8006) 9:51:35 AM ... ... ... 9/9/2023 Location B (8004) 8:31:50 PM 9/9/2023 Location D (8006) 10:34:26 PM 9/9/2023 Location D (8006) 10:39:53 PM 9/9/2023 Location C (8003) 11:48:46 PM 9/9/2023 Location C (8003) 11:50:33 PM
期望输出格式:
{'9/03/23' : {'Location A' : [list of times],...,'Location D' : [list of times]},...,'9/09/23' : ...}
编写的函数代码:
def calls_perDay_perStore(df): d = defaultdict(dict) arr = [] for i,row in df.iterrows(): d[row.Date][row.Store] = arr d[row.Date][row.Store].append(row.Time) dict(d) print(d)
问题:所有时间被追加到同一个数组中,无法按日期和门店正确分组。
解决方案
错误原因
你创建了一个全局的arr列表,每次循环都把这个同一个列表对象赋值给不同的日期和门店键,所以所有的append操作都会修改这个唯一的列表,导致所有时间混在一起。
方法1:修改循环逻辑(手动判断)
每次循环时,检查当前日期下的门店是否已存在列表,不存在则新建空列表再追加时间:
from collections import defaultdict def calls_perDay_perStore(df): d = defaultdict(dict) for _, row in df.iterrows(): date_key = row.Date store_key = row.Store # 检查当前日期下的门店是否已有列表,没有则新建 if store_key not in d[date_key]: d[date_key][store_key] = [] d[date_key][store_key].append(row.Time) # 转换为普通字典(可选) return dict(d)
方法2:使用嵌套defaultdict(更简洁)
用嵌套的defaultdict自动为不存在的日期和门店创建空列表,避免手动判断:
from collections import defaultdict def calls_perDay_perStore(df): # 外层是日期的defaultdict,内层是门店的defaultdict,默认值为空列表 d = defaultdict(lambda: defaultdict(list)) for _, row in df.iterrows(): d[row.Date][row.Store].append(row.Time) # 转换为普通字典(如果需要去掉defaultdict类型) return {k: dict(v) for k, v in d.items()}
方法3:用Pandas GroupBy(高效推荐)
对于大数据量,iterrows效率较低,直接用Pandas的分组功能更高效:
def calls_perDay_perStore(df): # 按Date和Store分组,将Time列转为列表 grouped = df.groupby(['Date', 'Store'])['Time'].apply(list).unstack() # 转换为目标嵌套字典格式 return grouped.to_dict('index')
内容的提问来源于stack exchange,提问作者EyTuZy
相关产品推荐
相关产品推荐

