使用numpy将csv文件加载到二维矩阵中以进行绘图

87

给定以下 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列的矩阵/ndarray加载。然而,由于某种原因,我只能从numpy得到一个有3行(每行一行)且没有列的ndarray。

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个回答

167

纯粹的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数组,这样可能更快。

我想补充一下,skiprows=1标志跳过了第一行,并且如果您想保留所有数据,则不是标准激活标志。完美地工作! - Arturo
loadtxt函数不会加载列名,如果需要加载列名,可以使用genfromtxt函数并设置names=True。 - mhstnsc
我可以问一下吗 - open 是局部的吗?也就是说,文件在该行结束时关闭吗? - Daniel Soutar
是的,它会关闭文件。另请参阅:https://dev59.com/02sz5IYBdhLWcg3wR1kc - Kaveh_kh
我建议使用第二种方法,因为loadtxt非常慢。或者,pandas非常适合此目的。 - fireball.1
1
@fireball.1,像这样的速度测试对于后人来说是非常有价值的。 - Akaisteph7

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])

有趣的是,在我的情况下,这并不会改变结果。我正在使用Python 2.5和numpy 1.4.1,所以可能是问题所在。 - dgorissen
我正在使用Python 2.6和NumPy 1.3.0!我更喜欢旧的行为。 - mtrw

4
你可以使用np.genfromtxt将带有标题的CSV文件读入NumPy结构化数组。例如:
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 记录数组。虽然那种方法没有什么问题,但结构化数组通常比记录数组更好,因为速度更快且兼容性更好。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接