如何强制Pandas返回DataFrame视图以执行数据转换?
解决Pandas切片副本导致修改无效的问题
嘿,我懂你碰到的这个坑了——Pandas的切片有时候返回的是副本而非视图,导致你用apply修改的只是临时的副本,原merge DataFrame根本没变化。其实没必要硬钻牛角尖去强求获取视图(毕竟Pandas的视图/副本规则有时候确实有点绕),咱们换个更直接的思路就能搞定:
方案:直接定位原DataFrame的目标行修改
1. 先筛选出需要处理的行的索引
先把那些timestamp是-----且filepath以S1/S2开头的行的索引找出来,这样就能精准定位原DataFrame里的目标行:
# 构建筛选条件 mask = (merge["timestamp"] == '-----') & (merge["filepath"].str.startswith(("S1", "S2"))) # 获取目标行的索引 target_indices = merge[mask].index
2. 遍历索引直接修改原数据
然后咱们遍历这些索引,逐个读取图片元数据并更新原DataFrame的timestamp列。这种方式直接作用在原DataFrame上,完全绕开了副本的问题:
import PIL.Image from pathlib import Path path0 = Path("你的实际根路径") # 记得替换成你自己的根路径 for idx in target_indices: filepath = merge.loc[idx, "filepath"] try: img = PIL.Image.open(path0 / filepath) # 读取EXIF里的时间戳(标签306对应DateTime) exif_data = img._getexif() if exif_data and 306 in exif_data: merge.loc[idx, "timestamp"] = exif_data[306] except Exception as e: # 可以加个错误打印,方便排查哪行出了问题 print(f"处理文件 {filepath} 时出错: {str(e)}") continue
额外优化:用更稳定的方式读取EXIF
顺便提一句,_getexif()是PIL的私有方法,后续版本可能会变动,建议用更规范的方式读取EXIF:
from PIL.ExifTags import TAGS def get_exif_timestamp(img): exif_data = img.getexif() if not exif_data: return None # 遍历EXIF标签,找到DateTime字段 for tag_id, value in exif_data.items(): tag_name = TAGS.get(tag_id, tag_id) if tag_name == 'DateTime': return value return None # 然后在循环里替换成: timestamp = get_exif_timestamp(img) if timestamp: merge.loc[idx, "timestamp"] = timestamp
这样不仅兼容性更好,代码也更易读。
内容的提问来源于stack exchange,提问作者JP Zhang
相关产品推荐
相关产品推荐

