我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文以鸢尾花数据的Y数据为主要视角进行分析,大家都知道:鸢尾花的Y数据表示的是当前数据的标签分类。分别是:0表示山鸢尾(Iris Setosa),1表示变色鸢尾(Iris Versicolour),2表示维吉尼亚鸢尾(Iris Virginica)。本文的主要内容就是基于这个基本事实的。

苏南大叔:以鸢尾花数据集为例,numpy如何批量修改ndarray元素? - numpy修改ndarray内容
以鸢尾花数据集为例,numpy如何批量修改ndarray元素?(图2-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。测试环境:win10python@3.12.0numpy@1.26.1。本文分析的不是很好,待后续文章再次分析。

观察鸢尾花标签数据

这里再次回顾一下鸢尾花数据集,从数据集中解析出分类标签数据,也就是本文的目标数据。

from sklearn.datasets import load_iris
iris = load_iris()
print(iris["target"])        # [0 0 .. 1 1 .. 2 2..]
print(iris["target_names"])  # ['setosa' 'versicolor' 'virginica']

输出:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
['setosa' 'versicolor' 'virginica']

聚焦于下面的两个变量即可,这就是本文的龙套主角:

  • iris["target"],[0 0 .. 1 1 .. 2 2..]
  • iris["target_names"],['setosa' 'versicolor' 'virginica']

简易方案【推荐】

把数据列里面的数字变成英文,其实就是把其中的0都变成"setosa"字样,1变成"versicolor"字样,2变成"virginica"字样。

np.array(y_en)[y]

输出:

['setosa' 'setosa' .. 'versicolor' 'versicolor' .. 'virginica' 'virginica' ..]

把数据列里面的数字变成中文,代码是这样写的:

y4 = np.array(["山鸢尾","变色鸢尾","维吉尼亚鸢尾"])[y]

输出:

['山鸢尾' '山鸢尾' .. '变色鸢尾' '变色鸢尾' .. '维吉尼亚鸢尾' '维吉尼亚鸢尾' ..]

简易逆向操作【失败】

把数字变成文字的做法,和机器学习的通用做法是背道而驰的。机器学习的做法,通常是把文字变成数字,然后做各种加工预测。
所以,这里试图做一下逆向操作。然而,在本文中的类似方案,却失败了。

y5 = np.array([0,1,2])[y4]

提示信息是:

IndexError: arrays used as indices must be of integer (or boolean) type
IndexError: 用作索引的数组必须是整数(或布尔)类型

逆向操作新方案【成功】

为了实现下面的需求:"setosa"字样变回数字0,"versicolor"字样变成数字1,"virginica"字样变成数字2。完整代码:

from sklearn.datasets import load_iris
iris = load_iris()
y = iris["target"]

import numpy as np
y2 = np.array(["山鸢尾","变色鸢尾","维吉尼亚鸢尾"])[y]
print(y2)

# 反过来操作失败
# y3 = np.array([0,1,2])[y2]
# IndexError: arrays used as indices must be of integer (or boolean) type

# 另辟蹊径
y3 = y2.copy()
y3[np.where(y3 == '山鸢尾')] = 0
y3[np.where(y3 == '变色鸢尾')] = 1
y3[np.where(y3 == '维吉尼亚鸢尾')] = 2

# 验证是否成功
print(np.array_equal(y,y3)) # False 类型没变
y3 = y3.astype(int)
print(np.array_equal(y,y3)) # True
print(y3)

输出:

['山鸢尾' '山鸢尾' .. '变色鸢尾' '变色鸢尾' .. '维吉尼亚鸢尾' '维吉尼亚鸢尾' ..]
False
True
[0 0 .. 1 1 .. 2 2 ..]

参考文章:

苏南大叔:以鸢尾花数据集为例,numpy如何批量修改ndarray元素? - 转化代码两种方案
以鸢尾花数据集为例,numpy如何批量修改ndarray元素?(图2-2)

对数据的格式要求

左侧被操作的新元素列表,可以比实际需要的多,但是不能少。
右侧被操作的变量y是有要求的,要求是以数字或者布尔型为元素。这里必须存在数字0,以0开始。

np.array([ 'blue','red','green' ])[ [1,1,0] ]       #  ['red' 'red' 'blue']
np.array([ 'blue','red' ])[ [1,1,0] ]               #  ['red' 'red' 'blue']
np.array([ 'blue','red' ])[ [ [0,1,1], [1,1,0] ] ]  #  [['blue' 'red' 'red'] ['red' 'red' 'blue']]

实际上的运算结果就是:左侧list的第零个元素(也可能是个数组)替换右侧的数字0,以此类推。

np.array([ 'blue' ])[ [1,1,0] ]         # 左侧不够
# IndexError: index 1 is out of bounds for axis 0 with size 1
np.array([ 'blue','red' ])[ [1,1,2] ]   # 右侧没有从0开始
# IndexError: index 2 is out of bounds for axis 0 with size 2
np.array([ 'blue','red' ])[ [True,True,False] ] # 这个也报错了...
# IndexError: boolean index did not match indexed array along dimension 0; dimension is 2 but corresponding boolean dimension is 3

相关文章

总结

这个精准替换内容的操作,是相当的思路清奇。numpy总是有很多类似的思路清奇的操作。所以,为啥说numpy是科学计算领域的神器呢。对吧?

更多苏南大叔的python相关经验文章,敬请参考:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python