【问题标题】:Too many indices for array while slicing切片时数组索引过多
【发布时间】:2018-03-27 18:40:54
【问题描述】:

我在尝试切片时收到错误“IndexError: too many indices for array”。

我可以打印数组的每个字段,如下所示:

vector = np.random.choice(data)
print(vector)
vec1 = vector[-1]
print(vec1)
vec2 = vector[1]
print(vec2)

(5.5, 2.5, 4., 1.3, '鸢尾花')

鸢尾花

2.5

当我添加那行时:

vec3 = vector[:-1]

我收到错误:

IndexError: 数组索引过多

这可能是什么问题?

//编辑

我从 iris 文件中获取数据

names = ['sepal length', 'sepal width', 'petal length', 'petal width', 'class']
data = np.genfromtxt('iris.data', delimiter=',', dtype=None, encoding=None, names=names)

我还检查了 vecotr 的类型

print(type(vector))

类'numpy.void'

【问题讨论】:

  • 你真的应该在问调试问题时发minimal reproducible example
  • 初始化vector = (5.5, 2.5, 4., 1.3, 'Iris-versicolor'),我没有收到任何错误。所以一定有其他原因导致了这个问题。请举一个完整的例子。
  • genfromtxt 带有这些参数会返回一个结构化数组。查看data.dtypedata.shape。然后vector 是相同dtype 的单个元素数组。

标签: python numpy slice


【解决方案1】:

这与@user2357112的解释基本相同:

In [82]: data = np.array([(5.5, 2.5, 4., 1.3, 'Iris-versicolor')],dtype='f,f,f,f,U20')
In [83]: vector = np.random.choice(data)
In [84]: vector
Out[84]: (5.5, 2.5, 4., 1.3, 'Iris-versicolor')
In [85]: vector[-1]
Out[85]: 'Iris-versicolor'
In [86]: vector[1]
Out[86]: 2.5
In [87]: vector[:-1]
IndexError: too many indices for array
In [88]: vector.dtype
Out[88]: dtype([('f0', '<f4'), ('f1', '<f4'), ('f2', '<f4'), ('f3', '<f4'), ('f4', '<U20')])
In [89]: vector['f2']
Out[89]: 4.0

data 可能有更多元素,但没有更多参数的choice 仅返回一个,作为 0d 数组 (vector.shape)。

通常我们用字段名称索引结构化数组的字段,但可以通过数字访问它们。但是无法通过切片访问它们。

可以使用item 提取记录,生成tuple

In [90]: vector.item()
Out[90]: (5.5, 2.5, 4.0, 1.2999999523162842, 'Iris-versicolor')
In [91]: _[:-1]
Out[91]: (5.5, 2.5, 4.0, 1.2999999523162842)

也可以通过列表访问多个字段:

In [92]: vector.dtype.names
Out[92]: ('f0', 'f1', 'f2', 'f3', 'f4')
In [93]: vector.dtype.names[:-1]
Out[93]: ('f0', 'f1', 'f2', 'f3')
In [95]: vector[list(vector.dtype.names[:-1])]
Out[95]: (5.5, 2.5, 4., 1.3)

但是这个多字段名称代码一直在开发中,所以细节可能会因版本而异。

【讨论】:

  • 哦,是的,item() 存在。我倾向于忘记item() 并坚持使用tolist()
【解决方案2】:

您似乎从 NumPy 结构化数组或类似的东西中提取了一条记录。这条记录看起来像一个元组,但它实际上是numpy.voidnumpy.record 或一些相关类型的实例。要将其转换为元组,您可以使用

tup = vector.tolist()

(是的,tolist() 表示元组),然后您可以对结果执行普通的元组操作,包括切片。

【讨论】:

  • 这是一个合理的解释,尽管应该已经在vec2 = vector[1] 提出了异常。
  • @Falko: numpy.voidnumpy.record 支持索引,但不支持切片。我相信切片会导致关于内存布局和填充的混乱决策,但我并不完全了解所涉及的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-31
  • 2022-11-03
  • 2017-07-03
  • 2021-05-30
  • 1970-01-01
  • 2019-05-09
  • 2015-10-23
相关资源
最近更新 更多