使用NumPy修改ndarray元素时出现字符串截断的问题咨询
问题成因
这个问题和正则匹配逻辑无关,是NumPy 1.x版本定长字符串数组的默认行为导致的静默截断:
- 逐行创建
labelList时,NumPy会自动根据传入列表中最长的字符串长度,为整个数组推断固定长度的字符串类型(dtype),类型标识为<Un,其中n代表每个数组元素最多可存储的字符数,创建完成后这个长度就固定无法修改。 - 处理1249行数据时,数组创建阶段的初始元素为
['1249', 'male', 'child', 'white', 'funny', ''],所有元素的最长长度为5(如child、white、funny均为5个字符),因此数组的dtype会被自动设为<U5,每个槽位最多容纳5个字符。 - 后续往索引4的位置赋值7个字符长度的
'smiling'时,由于槽位容量已经固定为5个字符,NumPy不会自动扩容,也不会抛出报错,只会静默截断超出长度的内容,最终只保留前5个字符'smili',丢失末尾的'ng'。
可以通过在创建数组后打印labelList.dtype验证,处理1249行时的数组类型确实是dtype('<U5')。
可行解决方法
手动指定足够长的字符串dtype,跳过自动推断的短长度限制:
修改数组创建代码,把原行:labelList = np.array(["".join(x) for x in match])替换为:
labelList = np.array(["".join(x) for x in match], dtype="<U20")直接将每个槽位的可存储长度设为20,只要后续赋值的字符串长度不超过20就不会出现截断。
先完成字符串替换逻辑,最后再转换为NumPy数组:
把原来的“先转数组再修改值”的逻辑,改成先用普通Python列表处理所有替换操作,确认所有值都确定后再生成NumPy数组,此时自动推断的dtype会把替换后的长字符串也算入长度统计,不会出现截断:# 先用普通列表处理,不要提前转numpy数组 label_list = ["".join(x) for x in match] if label_list[4] == 'funny': label_list[4] = 'smiling' # 所有替换完成后再转数组 labelList = np.array(label_list)如果后续需要频繁修改数组内字符串的长度,也可以创建数组时指定
dtype=object,此时数组元素存储的是Python原生字符串对象的引用,不会存在固定长度限制,但这种方式会损失NumPy字符串数组的内存与运算效率,仅适合对性能要求不高的场景。
内容的提问来源于stack exchange,提问作者iwho
相关产品推荐
相关产品推荐

