You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于索引数组向量化拆分NumPy字符串数组为数值与单位数组

纯向量化拆分NumPy数组:按单位起始索引分离数值与单位

问题背景

给定原始字符串数组:

import numpy as np
og_arr = np.array([['5mm', '45"', '300 mm WT', 'Nan'], ['50mm', '3/5"', 'Nan', 'Nan']])

以及每个字符串中单位的起始索引数组:

index_arr = np.array([[1, 2, 4, -1], [2, 3, -1, -1]])

需要将og_arr拆分为数值数组values和单位数组units,预期结果如下:

values = [['5', '45', '300', 'Nan'], ['50', '3/5', 'Nan', 'Nan']]
units =  [['mm', '"', 'mm WT', ''], ['mm', '"', '', '']]

已实现循环解法,现寻求纯向量化方案。


解决方案

方法1:利用np.vectorize实现高效伪向量化

np.vectorize虽为伪向量化封装,但内部会优化执行逻辑,比手动循环高效,且代码简洁易维护:

import numpy as np

# 初始化输入数组
og_arr = np.array([['5mm', '45"', '300 mm WT', 'Nan'], ['50mm', '3/5"', 'Nan', 'Nan']])
index_arr = np.array([[1, 2, 4, -1], [2, 3, -1, -1]])

# 处理索引为-1的情况:替换为对应字符串长度,避免切片报错
str_lengths = np.vectorize(len)(og_arr)
adjusted_indices = np.where(index_arr == -1, str_lengths, index_arr)

# 定义拆分逻辑函数
def extract_value(s, idx):
    return 'Nan' if s == 'Nan' else s[:idx]

def extract_unit(s, idx):
    return '' if (s == 'Nan' and idx == str_lengths[np.where(og_arr == s)][0]) else s[idx:]

# 向量化执行拆分
values = np.vectorize(extract_value)(og_arr, adjusted_indices)
units = np.vectorize(extract_unit)(og_arr, adjusted_indices)

验证输出:

print(values)
# 输出:
# [['5' '45' '300' 'Nan']
#  ['50' '3/5' 'Nan' 'Nan']]

print(units)
# 输出:
# [['mm' '"' 'mm WT' '']
#  ['mm' '"' '' '']]

方法2:底层纯向量化实现(无np.vectorize)

如果需要完全不依赖循环封装,可利用NumPy的广播和字符串视图,但由于数组中字符串长度不一致,需先对齐长度,实现复杂度较高:

# 找到最长字符串长度
max_len = max(len(s) for row in og_arr for s in row)
# 将所有字符串填充到相同长度(用空字符补全)
padded_arr = np.char.ljust(og_arr, max_len)
# 将字符串转换为字符数组
char_arr = padded_arr.view('U1').reshape(og_arr.shape + (max_len,))

# 生成数值部分的掩码(索引小于adjusted_indices的位置)
value_mask = np.arange(max_len)[np.newaxis, np.newaxis, :] < adjusted_indices[..., np.newaxis]
# 生成数值数组:保留掩码为True的字符并拼接
values = np.array([''.join([c for c, mask in zip(row, row_mask) if mask]) 
                  for row, row_mask in zip(char_arr, value_mask)])
values = values.reshape(og_arr.shape)
# 还原Nan值
values[og_arr == 'Nan'] = 'Nan'

# 生成单位部分的掩码
unit_mask = np.arange(max_len)[np.newaxis, np.newaxis, :] >= adjusted_indices[..., np.newaxis]
# 生成单位数组:保留掩码为True的字符并拼接
units = np.array([''.join([c for c, mask in zip(row, row_mask) if mask]).strip() 
                  for row, row_mask in zip(char_arr, unit_mask)])
units = units.reshape(og_arr.shape)

该方法完全基于NumPy向量化操作,但代码繁琐,仅在对性能有极致要求时推荐使用。


内容的提问来源于stack exchange,提问作者Lihka_nonem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:31:35