【问题标题】:ValueError: setting an array element with a sequence. on data read from csvValueError:使用序列设置数组元素。从 csv 读取的数据
【发布时间】:2018-09-13 02:55:50
【问题描述】:

我正在尝试逐行从 csv 加载数据,然后从每一行创建 2d 数组并将其存储在数组中:

正在加载:

with open('data_more.csv', newline='') as csvfile:
    data = list(csv.reader(csvfile))

解析:

def getTrainingData():
    label_data = []
    for i in range( 0 , len(data) - 1):
        y = list(data[i][1:41:1])
        y = list(map(lambda x: list(map(lambda z: int(z),x)),y))
        y = create2Darray(y)
        label_data.append(y)
    labelY = np.array(label_data,dtype=float)

create2Darray 函数:

def create2Darray( arr ):
    final_arr = []
    index = 0
    while( index < len(arr)):
        temp = arr[index:index+4:1]
        final_arr.append(temp)
        index+=4
    return final_arr

这是一个简单的任务,但我不断收到错误:

ValueError: 使用序列设置数组元素。

我读过它与元素形状不同时的情况有关。但是,当我打印 labelY 内所有元素的形状时,它会输出相同的形状。

那么是什么导致了这个问题呢?问题出现在这一行

labelY = np.array(label_data,dtype=float)

我的 csv 有格式

number, number, number

行中基本上有 N 个数字,用“,”分隔,example 感谢您的帮助。

【问题讨论】:

  • 你的变量data是什么样的?
  • 你试过np.genfromtxt吗?
  • 我的数据变量看起来像二维数组(至少在打印之后)
  • 如何使用pandas 读取csv 并执行操作,然后使用lociloc 将它们切片成series,这将直接转换为np.array .您还可以使用.dropna() 删除NoneType 的任何值
  • @iam.Carrot 你介意举个例子吗?我对python不是很熟悉。谢谢

标签: python python-3.x numpy


【解决方案1】:

从您的链接复制粘贴:

In [367]: txt="""frame_video_02_0.jpg,126,37,147,112,100,41,126,116,79,34,96,92,
     ...: 68,31,77,88,1
     ...: """
In [368]: txt=txt.splitlines()
In [369]: data =np.genfromtxt(txt, delimiter=',')

data 是一个二维浮点数组:

In [370]: data.shape
Out[370]: (3, 401)
In [371]: data[0,:10]
Out[371]: array([ nan, 126.,  37., 147., 112., 100.,  41., 126., 116.,  79.])

第一列是nan,因为它是一个不能做成浮点数的文本。我可以用data = data[:, 1:]删除它

我可以单独加载文件名:

In [373]: labels = np.genfromtxt(txt, delimiter=',', usecols=[0],dtype=None,encoding=None)
In [374]: labels
Out[374]: 
array(['frame_video_02_0.jpg', 'frame_video_02_50.jpg',
       'frame_video_02_100.jpg'], dtype='<U22')

我还没有尝试调试您的代码,尽管使用这样的文件,将数字读入 Python 列表应该不难。

【讨论】:

  • 为什么不直接将range(1,41) 传递给usecols
  • @MadPhysicist。我懒得用这么复杂的usecols参数了!
  • 我不确定它是否会起作用。希望你能为我测试一下:)
  • 范围确实有效 - 但您必须提前知道有多少列。
  • @hpaulij。 OP 似乎有一个特定的数字。 2D 转换意味着他们始终想要 4 的倍数。
【解决方案2】:

让我们从头开始:

  1. 您似乎想遍历文件的每一行以创建一个数组。迭代应该超过range(0, len(data)),而不是range(0, len(data) - 1):范围的最后一个元素是独占,因此您当前正在跳过最后一行。其实你可以简单写range(len(data)),或者更Pythonic的,这样做

    for y in data:
        y = y[1:41]
    
  2. 根据后面的内容,您需要从第二个元素开始的 y 的 40 个元素。在这种情况下,y[1:41] 是正确的(您不需要尾随的:1)。如果您不是要跳过第一个元素,请使用y[0:40],或者更符合Python 语言的y[:40]。请记住,索引是从零开始的,而停止索引是独占的

  3. y 列表中的每个元素不是一个数字。它是一个字符串,可以从文件中读取。通常,您可以使用

    将其转换为数字列表
    y = [float(x) for x in y]
    

    y = list(map(float, y))
    

    您的代码是为每个元素创建一个嵌套列表,并按其数字进行拆分。这真的是你想要的吗?从问题的其余部分来看,它肯定不是那样的。

  4. create2Darray 似乎需要一个4n 数字列表,并将其分解为大小为n-by-4 的二维列表。如果此时你想继续使用纯 Python,可以使用range 缩短代码:

    def create2Darray(arr):
        return [arr[i:i + 4] for i in range(0, len(arr), 4)]
    
  5. 2D 操作的结果被附加到带有label_data.append(y) 的 3D 列表中。目前,由于数字拆分,label_data 是一个具有参差不齐的第 4 维的 4D 列表。以这种方式附加列表是非常低效的。在for 循环的主体中包含一个包含语句的小函数会更好,并在列表推导中使用它。
  6. 最后,将 4D 数组(可能应该是 3D)转换为 numpy 数组。此操作失败,因为您的号码并非都具有相同的位数。一旦你修复了第 3 步,错误就会消失。当您将所有内容显式转换为 int 时,仍然存在为什么要使用 dtype=np.float 的问题,但这需要您自己弄清楚。
  7. 别忘了给getTrainingData添加一个返回值!

TL;DR

不过,您真正可以做的最简单的事情是在将文件转换为 2D numpy 数组后进行所有转换。你的程序可以重写为

with open('data_more.csv', newline='') as file:
    reader = csv.reader(file)
    data = [float(x) for x in line[1:] for line in reader]
data = np.array(data).reshape(data.shape[0], -1, 4)

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2018-08-04
    • 2019-08-04
    相关资源
    最近更新 更多