如何翻转NumPy矩阵列值:保留NaN并替换重复值为对应翻转值
实现NumPy矩阵列值翻转(保留NaN并统一替换重复值)
根据输入输出示例,实际需求可明确为:对NumPy矩阵的每一列,保留原有的NaN值,同时将列中非NaN唯一值按首次出现顺序组成的序列翻转,并将原列中所有重复的非NaN值统一替换为翻转序列中对应位置的值。
解决方案代码
import numpy as np def flip_column_values(arr): result = arr.copy() for col_idx in range(arr.shape[1]): col_data = arr[:, col_idx] # 提取非NaN值并获取按首次出现顺序排列的唯一值 non_nan_vals = col_data[~np.isnan(col_data)] unique_vals, idx = np.unique(non_nan_vals, return_index=True) unique_vals_sorted = unique_vals[np.argsort(idx)] # 翻转唯一值序列并创建映射 flipped_vals = unique_vals_sorted[::-1] val_mapping = dict(zip(unique_vals_sorted, flipped_vals)) # 替换非NaN值 non_nan_mask = ~np.isnan(col_data) result[non_nan_mask, col_idx] = np.array([val_mapping[v] for v in col_data[non_nan_mask]]) return result # 测试示例 A = np.array([ [1.0, 2.0, 3.0], [np.nan, 2.0, np.nan], [2.0, 1.0, np.nan], [3.0, np.nan, 1.0] ]) A_flipped = flip_column_values(A) print(A_flipped)
输出结果
[[ 3. 1. 1.] [nan 1. nan] [ 2. 2. nan] [ 1. nan 3.]]
代码说明
- 复制原矩阵:避免直接修改输入矩阵,保证原数据不受影响。
- 遍历列处理:对每一列单独操作:
- 提取列中的非NaN值,再通过
np.unique结合return_index参数,获取按首次出现顺序排列的唯一值序列。 - 翻转该唯一值序列,创建原值到翻转后值的字典映射。
- 利用布尔掩码定位非NaN位置,通过映射替换对应的值,NaN位置保持不变。
- 提取列中的非NaN值,再通过
性能优化(针对大矩阵)
如果处理大规模矩阵,可将列表推导式替换为矢量化操作,提升效率:
# 替换原列表推导式的部分 non_nan_mask = ~np.isnan(col_data) # 通过搜索排序获取索引,直接索引翻转后的序列 value_indices = np.searchsorted(unique_vals_sorted, col_data[non_nan_mask]) result[non_nan_mask, col_idx] = flipped_vals[value_indices]
内容的提问来源于stack exchange,提问作者Johannes Wiesner
相关产品推荐
相关产品推荐

