我正在尝试将列名添加到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] ))
基于维度的诊断符合我的预期:
print len(csv_names)
>> 108
print data.shape
>> (1652, 108)
“print data.dtype.names”也会返回预期的输出。
但是当我开始按字段名称调用列时,会发生棘手的事情。 “列”仍然是一个包含108列的数组......
print data["EDUC"].shape
>> (1652, 108)
...它似乎包含的缺失值多于数据集中的行。
print np.sum(np.isnan(data["EDUC"]))
>> 27976
知道这里出了什么问题吗?添加标题应该是一个简单的操作,但我已经打了几个小时这个bug。救命啊!
答案 0 :(得分:15)
问题是你在考虑类似电子表格的数组,而NumPy确实使用不同的概念。
以下是你必须了解的NumPy:
在你的情况下,NumPy会因此获取你的二维常规数组并生成一个一个维数组,其类型是一个108元素的元组(你想到的电子表格数组是2维)。
这些选择可能是出于效率原因而做出的:数组的所有元素都具有相同的类型,因此具有相同的大小:它们可以在低级别,非常简单快速地访问。
现在,正如user545424所示,对你想要做的事情有一个简单的NumPy答案(genfromtxt()
接受带有列名的names
参数。)
如果要将数组从常规NumPy ndarray转换为结构化数组,可以执行以下操作:
data.view(dtype=[(n, 'float64') for n in csv_names]).reshape(len(data))
(你很接近:你使用astype()
代替view()
)。
您还可以查看相当多的Stackoverflow问题的答案,包括Converting a 2D numpy array to a structured array和how to convert regular numpy array to record array?。
答案 1 :(得分:3)
不幸的是,当你尝试添加字段名称时我不知道发生了什么,但我知道你可以通过
直接从文件构建你想要的数组。data = np.genfromtxt(csv_file, delimiter=',', names=True)
编辑:
似乎添加字段名称仅在输入是元组列表时才有效:
data = np.array(map(tuple,data), [(n, 'float64') for n in csv_names])