如何在Python中将csv值形式的文件存储到numpy数组中?

时间:2020-03-29 15:53:06

标签: python arrays numpy csv hex

我编写了一个Python脚本,该脚本读取b&w位图图像,并将每个像素的值存储为.txt文件中从0x00到0xFF的十六进制值。这些值存储为一个连续的一维数组,用逗号分隔,并且为了没有非常宽的文件,这些行仅 最长为 16个元素,例如:

v01, v02, ... , v15, v16,
v17, v18, ... , v31, v32,
...
0x00, 0x00, ... , 0x00, 0x00,
0x00, 0x00, ... , 0x00, 0x00,
...

请注意,每行的最后一个元素也有一个逗号

.txt文件当然不会保留位图的原始尺寸,但这不是问题,因为稍后它将在微控制器固件中使用,该固件知道原始尺寸并负责正确读取一维数组。

现在,为了验证转换是否正确完成,我需要编写一个脚本来读取文件并将值存储在numpy数组中,该数组用于以后通过“ matplotlib”显示图像。 我尝试了以下代码:

my_data = genfromtxt('file.txt', delimiter=',')
print(my_data)

问题在于,除了错误的尺寸外,十六进制值不被读取为数字,并且行的最后一个逗号之后的元素也被读取(我猜是断字符)。我得到类似的东西:

[nan, nan, ... , nan, nan," "
...]

我需要一种方法来读取.txt文件,将值从“ 0x00”格式转换为数值,然后存储在amxn numpy数组中(m和n是已知参数,原始位图大小):

[[0, 0, ... , 0, 0]
 [0, 0, ... , 0, 0]
 ...]

有关如何操作的任何建议?


更新

在撰写问题时,我仅使用宽度为16像素倍数的文件,这可以确保csv输出在所有行中始终具有16个元素。但是经过一些测试,我发现了一张图片,该图片的大小使csv的最后一行少于16个元素。在那种情况下,我无法使用@taras提供的解决方案,但按照我最初的问题,答案仍然是正确的。

最后,我得到了以下代码,也许不那么优雅,但是可以解决问题:

with open(filename,"r") as f:
        pixels=[x.split(',') for x in f.readlines()]
        for p in pixels:
            del p[-1]
        pixels = [int(p,16) for row in pixels for p in row]
        pixels = np.asarray(pixels, dtype=np.uint8).reshape(h,w)

我会保留两个答案,以防有人觉得有用。

1 个答案:

答案 0 :(得分:1)

由于列数固定,您可以利用它仅读取前16列(它将使您去除尾随的逗号),并使用converters dict和{ {1}}:

int(x, 16)

修改:
如果文件中的元素数量不是16的倍数,则可以使用常规的python代码预处理数据,然后将其转换为numpy数组:

import numpy as np

fname = 'file.txt'
num_cols = 16
np.loadtxt(fname, usecols=range(num_cols), dtype=np.uint8, delimiter=',',
           converters={k: lambda x: int(x, 16) for k in range(num_cols)})