【问题标题】:IndexError: too many indices for array. Numpy array with 42 features not homogeneousIndexError:数组的索引过多。具有 42 个特征的 Numpy 数组不均匀
【发布时间】:2016-09-10 02:59:26
【问题描述】:

我正在尝试实例化我的分类测试集,加载一个包含 41 个特征和 1 个标签的数据集:

import numpy as np

f = open("mydataset")
dataset = np.genfromtxt(f, delimiter=',', dtype=None)

X = dataset[:, 0:40]  # select columns 1 through 41
y = dataset[:, 41]  # select column 42 (the labels)

由于 mydataset 不是同质的(并非所有元素都具有相同的类型),函数 genfromtxt 创建一个一维数组(元组列表)。所以我得到这个错误:

X = dataset[:, 0:40]  # select columns 1 through 41
IndexError: too many indices for array

我该如何解决这个问题?我是否必须将 numpy 数组转换为 2D(如果是,以哪种方式)?还是我必须使用其他方式来选择正确的列?

谢谢

【问题讨论】:

    标签: python arrays numpy scikit-learn classification


    【解决方案1】:

    你可以定义一个复合数据类型:

    dt = np.dtype([('values',float,(41,)),('labels','S10')])
    data=np.genfromtxt(f, delimiters=',',dtype=dt)
    X = data['values']
    Y = data['labels']
    

    (未测试,因为我没有这种大小的样本数组)。

    正如我在最近的回答中所描述的,https://stackoverflow.com/a/37126091/901925

    您可以将dtype=None 数据转换为这种复合数据类型

    data.view(dt)
    

    虽然这要求所有数字都加载为浮点数(或全部为整数)。通常 CSV 混合了浮点和整数列,因此 None genfromtxt 调用的数字字段将是混合类型。

    借用其他答案,一般结构化数组可能如下所示:

    In [421]: data=np.array([('label1', 12, 23.2, 232.0), ('label2', 23, 2324.0, 324.0),
           ('label3', 34, 123.0, 2141.0), ('label4', 0, 2.0, 3.0)], 
          dtype=[('f0', '<U10'), ('f1', '<i4'), ('f2', '<f8'), ('f3', '<f8')])
    

    4 个具有不同 dtype 的字段。

    可以通过名称访问各个字段:data['f0'],或名称列表data[['f0','f3']]。但是你可以用名字列表做的事情是有限的。

    In [426]: data[['f2','f3']]=10
    ...
    ValueError: multi-field assignment is not supported
    

    如果你做一个副本,你可以做得更多,如果你把它看作是同构数组,你可以做得更多:

    In [427]: d23=data[['f2','f3']].copy()
    
    In [428]: d23
    Out[428]: 
    array([(23.2, 232.0), (2324.0, 324.0), (123.0, 2141.0), (2.0, 3.0)], 
          dtype=[('f2', '<f8'), ('f3', '<f8')])
    
    In [429]: d23=d23.view((float,(2,)))
    
    In [430]: d23
    Out[430]: 
    array([[  2.32000000e+01,   2.32000000e+02],
           [  2.32400000e+03,   3.24000000e+02],
           [  1.23000000e+02,   2.14100000e+03],
           [  2.00000000e+00,   3.00000000e+00]])
    
    In [431]: d23+=34
    
    In [432]: d23
    Out[432]: 
    array([[   57.2,   266. ],
           [ 2358. ,   358. ],
           [  157. ,  2175. ],
           [   36. ,    37. ]])
    

    (更改为d23 不会影响原来的data)。

    【讨论】:

    • 我还有一个问题,41个特征也不是同质的(有些是字符串)
    • 我添加了一些访问结构化数组的示例,这些示例可能使用dtype=None 生成。
    • 谢谢@hpaulj!相反,如果我使用 for 循环创建列表列表(一次传递一个原始列表)然后将其转换为 nparray,您会怎么想?是否适用于不同类型的字段?
    • 最好是在一个新问题中问最后一个问题——举个例子。
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多