【问题标题】:Trouble accessing column data by name按名称访问列数据时遇到问题
【发布时间】:2014-02-01 05:50:32
【问题描述】:

我无法通过列名从结构化 numpy 数组中获取数据。最后是我的相关代码。我认为它足够简单和简短,可以完整发布(实际上是一个 sscce)。

如果test.out 文件不存在,则将其简单地生成数据。我总是从文件中加载数据,只是为了测试目的。这里不重要(我认为)。然后,如果文件中的数据是同质的,我会强制使用结构化数组。我想通过像data['f3'] 这样的列名来访问数据,但我得到了一种奇怪的形状。我得到一个单元素列表的列表。例如:

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

【问题讨论】:

    标签: python arrays python-3.x numpy


    【解决方案1】:

    当您分配新的 dtype 以使 data 成为结构化数组时,形状从 (10, 10) 更改为 (10, 1)。也就是说,它仍然是一个二维数组,第二维长度为 1。如果结构化数组是由genfromtxt 创建的,则形状将是 (10,)(即它将是一维数组)。您也可以通过在分配 dtype 后分配一个新形状来完成相同的操作:

      data.shape = data.shape[0]
    

    或将data.dtype = new_dtype替换为

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

    那么结构化数组的形状为 (10,),data['f3'] 的形状也为 (10,)。

    请注意,从结构化数组中获取字段,例如data,是一个与data具有相同形状的数组。也就是说,data['f3'] 始终具有与data 相同的形状。它是结构化数组的“f3”字段的数组。我们经常将字段视为“列”(尤其是当结构化数组为 1-d 时),但实际上它们只是结构中字段的名称。

    【讨论】:

    • 我知道结构化数组是一维元组数组,这就是它们具有相同形状的原因。有没有办法正确设计new_dtype 以获得所需的形状?我认为按名称选择或按列选择有点像过滤器,我想知道这种访问方法是否存在任何复制开销,因为data['f3']data 似乎返回不同的元组。但这只是好奇,无论是 copy 还是 view。我还想知道我是否应该更喜欢您建议的其他方法。
    • 我不知道。我建议尝试通过在genfromtxt 中使用names 参数来避免该问题,但是如果您事先不知道列数,那并没有真正的帮助,正如您所发现的那样:stackoverflow.com/questions/21042294/…
    • 语句data = data.view(new_dtype).reshape(-1) 创建底层数据数组的新视图,而不是副本。而data['f3'] 也是一个视图——尝试设置data['f3'][0] = -1,然后检查data
    • 是的,令人费解的是,它是如此接近于可以实现,但有一点让它在两个用例中失败,也许我应该请一些 numpy 官员允许它,或者告诉我怎么做。无论如何感谢您的洞察力和回答,它的工作原理。
    猜你喜欢
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 2019-10-21
    • 1970-01-01
    • 2018-12-11
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多