用numpy将csv加载到2D矩阵以便绘图

88 投票
3 回答
239336 浏览
提问于 2025-04-16 07:49

给定这个CSV文件:

"A","B","C","D","E","F","timestamp"
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291111964948E12
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291113113366E12
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291120650486E12

我只是想把它加载成一个有3行7列的矩阵/数组。但是,不知道为什么,我从numpy中得到的结果只有3行(每行对应文件中的一行),却没有列。

r = np.genfromtxt(fname,delimiter=',',dtype=None, names=True)
print r
print r.shape

[ (611.88243, 9089.5601000000006, 5133.0, 864.07514000000003, 1715.3747599999999, 765.22776999999996, 1291111964948.0)
 (611.88243, 9089.5601000000006, 5133.0, 864.07514000000003, 1715.3747599999999, 765.22776999999996, 1291113113366.0)
 (611.88243, 9089.5601000000006, 5133.0, 864.07514000000003, 1715.3747599999999, 765.22776999999996, 1291120650486.0)]
(3,)

我可以手动遍历这个数据,把它调整成我想要的形状,但这感觉太麻烦了。我只想把它加载成一个合适的矩阵,这样我就可以在不同的维度上切片并绘图,就像在matlab中那样。

3 个回答

4

你可以用 NumPy 的结构化数组 来读取带有表头的 CSV 文件,使用的方法是 np.genfromtxt。比如说:

import numpy as np

csv_fname = 'file.csv'
with open(csv_fname, 'w') as fp:
    fp.write("""\
"A","B","C","D","E","F","timestamp"
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291111964948E12
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291113113366E12
611.88243,9089.5601,5133.0,864.07514,1715.37476,765.22777,1.291120650486E12
""")

# Read the CSV file into a Numpy record array
r = np.genfromtxt(csv_fname, delimiter=',', names=True, case_sensitive=True)
print(repr(r))

读取后数据的样子是这样的:

array([(611.88243, 9089.5601, 5133., 864.07514, 1715.37476, 765.22777, 1.29111196e+12),
       (611.88243, 9089.5601, 5133., 864.07514, 1715.37476, 765.22777, 1.29111311e+12),
       (611.88243, 9089.5601, 5133., 864.07514, 1715.37476, 765.22777, 1.29112065e+12)],
      dtype=[('A', '<f8'), ('B', '<f8'), ('C', '<f8'), ('D', '<f8'), ('E', '<f8'), ('F', '<f8'), ('timestamp', '<f8')])

你可以这样访问某一列的数据,比如 r['E']

array([1715.37476, 1715.37476, 1715.37476])

注意:之前这个回答使用了 np.recfromcsv 来把数据读入 NumPy 的记录数组。虽然这种方法没有问题,但结构化数组通常在速度和兼容性方面更好。

6

我觉得在有名称行的情况下使用 dtype 会让这个过程变得混乱。你可以试试下面的代码:

>>> r = np.genfromtxt(fname, delimiter=',', names=True)
>>> r
array([[  6.11882430e+02,   9.08956010e+03,   5.13300000e+03,
          8.64075140e+02,   1.71537476e+03,   7.65227770e+02,
          1.29111196e+12],
       [  6.11882430e+02,   9.08956010e+03,   5.13300000e+03,
          8.64075140e+02,   1.71537476e+03,   7.65227770e+02,
          1.29111311e+12],
       [  6.11882430e+02,   9.08956010e+03,   5.13300000e+03,
          8.64075140e+02,   1.71537476e+03,   7.65227770e+02,
          1.29112065e+12]])
>>> r[:,0]    # Slice 0'th column
array([ 611.88243,  611.88243,  611.88243])
168

纯粹使用numpy

numpy.loadtxt(open("test.csv", "rb"), delimiter=",", skiprows=1)

可以查看一下loadtxt的文档。

你也可以使用Python的csv模块:

import csv
import numpy
reader = csv.reader(open("test.csv", "rb"), delimiter=",")
x = list(reader)
result = numpy.array(x).astype("float")

你需要把数据转换成你喜欢的数字类型。我想你可以把整个过程写成一行代码:

result = numpy.array(list(csv.reader(open("test.csv", "rb"), delimiter=","))).astype("float")

附加提示:

你还可以使用pandas.io.parsers.read_csv,这样可以得到一个相关的numpy数组,这样可能会更快。

撰写回答