Python 读取CSV文件并附加到Numpy数组的新列

Python 读取CSV文件并附加到Numpy数组的新列,python,numpy,Python,Numpy,我正在读取CSV文件列表,并始终将数据附加到数组中的新列。我当前的解决方案类似于以下内容: 将numpy导入为np #为了再现性,随机发生器和路径 伪读csv=lambda路径:np.random.random(5) 路径=['a'、'b'、'c'、'd'] 第一次迭代=真 对于路径中的路径: 打印(f'读取路径{path}') sub=假读取csv(路径) 如果第一次迭代: 第一次迭代=错误 pred=sub 其他: pred=np.c_U8;[pred,sub]#追加到新列 打印(pred)

我正在读取CSV文件列表,并始终将数据附加到数组中的新列。我当前的解决方案类似于以下内容:

将numpy导入为np
#为了再现性,随机发生器和路径
伪读csv=lambda路径:np.random.random(5)
路径=['a'、'b'、'c'、'd']
第一次迭代=真
对于路径中的路径:
打印(f'读取路径{path}')
sub=假读取csv(路径)
如果第一次迭代:
第一次迭代=错误
pred=sub
其他:
pred=np.c_U8;[pred,sub]#追加到新列
打印(pred)
我想知道是否有可能简化循环。例如,类似这样的内容:

buffer = None
for col, path in enumerate(paths):
    data = fake_read_csv(path)
    if buffer is None:
        buffer = np.zeros((data.size, len(paths)))
    buffer[:, col] = data
将numpy导入为np
伪读csv=lambda路径:np.random.random(5)
路径=['a'、'b'、'c'、'd']
pred=np.array([])
对于路径中的路径:
打印(f'读取路径{path}')
sub=假读取csv(路径)
pred=np.c_U8;[pred,sub]#追加到新列
这会引发错误:

ValueError: all the input array dimensions except for the concatenation axis must match exactly

首先,每次追加都会分配一个全新的数组,这是非常浪费的。相反,您可以在加载所有列后将其合并:

pred = np.array([fake_read_csv(path) for path in paths], order='F').T
转置将您读入的行转换为列
order='F'
将确保转置结果的内存布局与问题中的数组相同

如果需要,可以通过预先知道行数或加载第一个数组来预先分配缓冲区。下面是后者的一个例子:

first = fake_read_csv(paths[0])
buffer = np.zeros((first.size, len(paths)))
buffer[:, 0] = first
for col, path in enumerate(paths[1:], start=1):
    buffer[:, col] = fake_read_csv(path)
如果您要多次调用reader函数,可以在循环中分配数组,如下所示:

buffer = None
for col, path in enumerate(paths):
    data = fake_read_csv(path)
    if buffer is None:
        buffer = np.zeros((data.size, len(paths)))
    buffer[:, col] = data

此选项的另一个优点是,它不会重新进行任何额外的检查以查看是否获得数据。

为什么要在
numpy
中执行此操作?也许可以这样使用:?@MrFuppes内存约束,但无论如何还是要感谢您的提示@费尔南多维特曼。建议的方法使用的内存应该比您考虑的要少得多。
pandas
,它便于处理csv和表格数据。@QuangHoang我目前正在使用pandas,但是,最后,我必须转换为
np.array
,以便用作Keras模型的输入。由于我可能有内存限制(每个CSV有1Gb),我正在考虑将每个文件直接读取到numpy数组中,而不是将所有文件作为数据帧读取,然后稍后再转换为numpy数组。感谢您提供的一行程序和缓冲区!然而,如果我不能使用列表理解,并且我不知道前面的行数,那么
fake\u read\u csv
必须在代码中出现两次,对吗?@FernandoWittmann。您可以将列表理解转换为for循环,但其思想是第一个循环同时单独加载所有列,然后连接它们(使用2N内存),而第二个循环预先分配缓冲区,一次只在内存中保存一个额外的列time@FernandoWittmann. 我添加了第三个选项,该选项与第二个选项相同,但只在循环内调用读取器。。