以编程方式将列名添加到numpy ndarray

Abe*_*Abe 13 python arrays numpy multidimensional-array

我正在尝试将列名添加到numpy ndarray中,然后按名称选择列.但它不起作用.当我添加名称时,或者稍后当我尝试调用它们时,我无法判断问题是否发生.

这是我的代码.

data = np.genfromtxt(csv_file, delimiter=',', dtype=np.float, skip_header=1)

#Add headers
csv_names = [ s.strip('"') for s in file(csv_file,'r').readline().strip().split(',')]
data = data.astype(np.dtype( [(n, 'float64') for n in csv_names] ))
Run Code Online (Sandbox Code Playgroud)

基于维度的诊断符合我的预期:

print len(csv_names)
>> 108
print data.shape
>> (1652, 108)
Run Code Online (Sandbox Code Playgroud)

"print data.dtype.names"也返回预期的输出.

但是当我开始按字段名称调用列时,就会发生棘手的事情."列"仍然是一个包含108列的数组......

print data["EDUC"].shape
>> (1652, 108)
Run Code Online (Sandbox Code Playgroud)

...它似乎包含比数据集中的行更多的缺失值.

print np.sum(np.isnan(data["EDUC"]))
>> 27976
Run Code Online (Sandbox Code Playgroud)

知道这里出了什么问题吗?添加标题应该是一个简单的操作,但我已经打了几个小时这个bug.救命!

Eri*_*got 15

问题是你正在考虑类似电子表格的数组,而NumPy确实使用不同的概念.

以下是您必须了解的NumPy:

  1. NumPy数组仅包含单个类型的元素.
  2. 如果您需要类似电子表格的"列",则此类型必须是类似元组的类型.这种数组称为结构化数组,因为它们的元素是结构(即元组).

在你的情况下,NumPy因此将采用你的二维规则数组并产生一个维数组,其类型是一个108元素的元组(你想到的电子表格数组是二维的).

这些选择可能是出于效率原因而做出的:数组的所有元素都具有相同的类型,因此具有相同的大小:它们可以在低级别,非常简单快速地访问.

现在,正如user545424所示,对你想要做的事情有一个简单的NumPy答案(genfromtxt()接受names带有列名的参数).

如果要将数组从常规NumPy ndarray转换为结构化数组,可以执行以下操作:

data.view(dtype=[(n, 'float64') for n in csv_names]).reshape(len(data))
Run Code Online (Sandbox Code Playgroud)

(你很亲密:你用的是astype()代替view()).

您还可以查看相当多的Stackoverflow问题的答案,包括将2D numpy数组转换为结构化数组以及如何将常规numpy数组转换为记录数组?.