Python按月份条件更新字典列表元素或追加数据的实现方法
问题说明
需要维护列表结构的字典存储时序数据,更新规则:
- 当日数据所属月份已存在时,替换对应月份的所有列表值
- 当日数据为新月份时,追加扩展对应列表值
初始数据构造:
import pandas as pd import numpy as np df_dict = pd.DataFrame({ 'orgnr': np.arange(1,6,1), 'periode': '2022-05', 'a':'tull', }).to_dict('list')
初始输出为标准列表型字典:
{'orgnr': [1, 2, 3, 4, 5], 'periode': ['2022-05', '2022-05', '2022-05', '2022-05', '2022-05'], 'a': ['tull', 'tull', 'tull', 'tull', 'tull']}
原有新月份追加逻辑可正常运行:
df_newMonth = pd.DataFrame({ 'orgnr': np.arange(1,6,1), 'periode': '2022-07', 'a':'new month', }).to_dict('list') for k, v in df_newMonth.items(): df_dict[k].extend(v)
同月份新一天数据更新时,原有update写法无法生效,原因是update会直接替换键对应的完整列表,不会定位到periode匹配的局部片段做替换。待更新的新日数据如下:
df_newDay = pd.DataFrame({ 'orgnr': np.arange(1,6,1), 'periode': '2022-07', 'a':'new day in new month', }).to_dict('list')
预期输出:
{'orgnr': [1, 2, 3, 4, 5, 1, 2, 3, 4, 5], 'periode': ['2022-05', '2022-05', '2022-05', '2022-05', '2022-05', '2022-07', '2022-07', '2022-07', '2022-07', '2022-07'], 'a': ['tull', 'tull', 'tull', 'tull', 'tull', 'new day in new month', 'new day in new month', 'new day in new month', 'new day in new month', 'new day in new month' ]}
适配现有存储结构的解决代码
先定位目标月份对应的索引区间,再做切片替换即可,同时兼容新月份追加场景:
target_month = '2022-07' # 匹配目标月份对应的所有索引位置 match_indexes = [i for i, month in enumerate(df_dict['periode']) if month == target_month] if match_indexes: # 月份已存在,切片替换对应段数据 start_pos, end_pos = match_indexes[0], match_indexes[-1] + 1 for col, new_values in df_newDay.items(): df_dict[col][start_pos:end_pos] = new_values else: # 月份不存在,直接追加新数据 for col, new_values in df_newDay.items(): df_dict[col].extend(new_values)
运行后即可得到预期输出。
更优存储方案建议
当前按列存列表、手动维护索引对齐的方式容错率极低,任意一列长度错配就会导致全量数据错位,更推荐两种易维护的方案:
- 直接使用pandas DataFrame存储
不需要手动维护索引对齐,更新逻辑极简,需要列表字典时调用一次to_dict('list')即可转换:# 统一用DataFrame存储 full_df = pd.DataFrame(df_dict) new_day_df = pd.DataFrame(df_newDay) # 删除同月份旧数据,拼接新数据 full_df = pd.concat([ full_df[full_df['periode'] != target_month], new_day_df ], ignore_index=True) # 需要列表字典时转换 df_dict = full_df.to_dict('list') - 采用月份为键的嵌套字典存储
不需要遍历全量列表查找索引,更新效率更高,结构示例如下:month_based_dict = { '2022-05': {'orgnr': [1,2,3,4,5], 'a': ['tull']*5}, '2022-07': {'orgnr': [1,2,3,4,5], 'a': ['new day in new month']*5} } # 更新时直接判断键是否存在,存在覆盖、不存在新增即可
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

