以鸢尾花数据集为例,numpy如何批量修改ndarray元素?
发布于 作者:苏南大叔 来源:程序如此灵动~本文以鸢尾花数据的Y
数据为主要视角进行分析,大家都知道:鸢尾花的Y
数据表示的是当前数据的标签分类。分别是:0
表示山鸢尾(Iris Setosa),1
表示变色鸢尾(Iris Versicolour),2
表示维吉尼亚鸢尾(Iris Virginica)。本文的主要内容就是基于这个基本事实的。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程经验文章。测试环境:win10
,python@3.12.0
,numpy@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 ..]
参考文章:
对数据的格式要求
左侧被操作的新元素列表,可以比实际需要的多,但是不能少。
右侧被操作的变量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
相关经验文章,敬请参考:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。