2014-01-13 67 views
1

我无法通过列名从结构化numpy数组获取数据。最后是我的相关代码。我认为它很简单并且足够短,可以被整体发布(这非常简单)。无法按名称访问列数据

如果test.out文件不存在,则会生成一个简单的数据生成代码。我总是从文件加载数据,仅用于测试目的。这里并不重要(我认为)。然后,如果文件中的数据是同质的,我强制使用结构化数组。我想通过像data['f3']这样的列名访问数据,但是我知道它的形状很古怪。我得到一个元素列表。 E.g:

shape: (10, 1), data['f3']: 
[[ 0.50308252] 
[ 0.16259077] 
[ 0.5448315 ] 
[ 0.77284975] 
[ 0.01443514] 
[ 0.40232731] 
[ 0.6703865 ] 
[ 0.3918904 ] 
[ 0.07649033] 
[ 0.70849585]] 

所需的输出将是:

shape: (10, 1), data['f3']: 
[ 0.50308252 0.16259077 0.5448315 0.77284975 0.01443514 0.40232731 
    0.6703865 0.3918904 0.07649033 0.70849585] 

有趣的是所有报告的形状相同(对于data.shape太)。

我是以错误的方式强制执行dtype吗?我非常肯定它可以做到,因为this answer显示与所需结果相同的语义。我想出了一个reshape的解决方法,但是如果有必要的话它似乎很奇怪。这也适用于列的列表。您可以在我的代码中设置col_name = ['f1', 'f3']。有没有办法用简单的data[col_name]完成它?

的代码:

import numpy 
import os 

def get_data(): 
    if not os.path.exists('test.out'): 
    new_data = numpy.random.rand(10,10) 
    numpy.savetxt('test.out', new_data, delimiter=',') 
    data = numpy.genfromtxt('test.out',delimiter=",", dtype=None) 
    return data 


def get_column(spreadsheet, column): 
    data = spreadsheet[column] 
    return data.reshape(data.shape[0]) 

data = get_data() 
#if data is homogenous, then forcibly transform into structured array 
if data.dtype.names is None: 
    new_dtype = list(map(lambda z:('f%d'%(z),data.dtype),range(0,data.shape[1]))) 
    #print('old dtype: {}, new dtype: {}'.format(data.dtype, new_dtype)) 
    data.dtype = new_dtype 

col_name = 'f3' 
print(data.dtype) 
print("shape: {}, data:\n{}".format(data.shape, data)) 
print("shape: {}, data['{}']:\n{}".format(data[col_name].shape, col_name, data[col_name])) 
print("shape: {}, data['{}']:\n{}".format(data[col_name].shape, col_name, get_column(data, col_name))) 

回答

2

当指定新D型细胞,使data结构化阵列,所述形状是从(10,10)变更为(10,1)。也就是说,它仍然是一个二维数组,具有长度为1的第二维。如果结构化数组由genfromtxt创建,则形状将是(10,)(即它将是一维数组)。

data.shape = data.shape[0] 

或用

data = data.view(new_dtype).reshape(-1) 

更换data.dtype = new_dtype那么结构阵列具有形状(10),和data['f3']也有形状:您可以通过分配D型后还分配一个新的形状达到相同的(10)。

注意,从结构化阵列得到一个字段,说data,是一个数组与相同形状data。也就是说,data['f3']总是具有与data相同的形状。它是结构化数组的'f3'字段的数组。我们经常将这些字段视为“列”(特别是当结构化数组为1-d时),但实际上它们只是结构中字段的名称。

+0

我得到的结构化数组是一维元组数组,这就是为什么它们具有相同的形状。有没有办法正确设计'new_dtype'来获得所需的形状?我认为按名称或列选择过滤器类型,我想知道是否有任何副本开销这种访问方法,因为它似乎像'data ['f3']'和'data'返回不同的元组。但它只是好奇心,无论它是一个*副本*还是一个*视图*。我也想知道是否应该比其他方法更适合你。 – luk32

+0

不是我所知道的。我建议通过在'genfromtxt'中使用'names'参数来避免这个问题,但是如果您事先不知道列的数量,那么这并没有什么帮助,正如您发现的那样:http:/ /堆栈溢出。com/questions/21042294/genfromtxt-force-column-name-generation-for-unknown-number-of-columns –

+0

语句'data = data.view(new_dtype).reshape(-1)'创建一个新的视图底层的数据阵列,而不是副本。 'data ['f3']'也是一个视图 - 尝试设置data ['f3'] [0] = -1',然后检查'data'。 –