Python 如何为每列使用不同的默认值初始化NumPy结构化数组?
我试图初始化一个大小为(x,y)的NumPy结构化矩阵,其中x的值是Python 如何为每列使用不同的默认值初始化NumPy结构化数组?,python,arrays,python-2.7,numpy,matrix,Python,Arrays,Python 2.7,Numpy,Matrix,我试图初始化一个大小为(x,y)的NumPy结构化矩阵,其中x的值是~10^3,y的值是~10^6 矩阵的第一列是ID(整数),其余的是三元组(int8),其中三元组的每个成员都应该有不同的默认值 i、 e.假设默认值为[2,5,9]我想初始化以下矩阵: 0 2 5 9 2 5 9 2 5 9 ... 0 2 5 9 2 5 9 2 5 9 ... 0 2 5 9 2 5 9 2 5 9 ... 0 2 5 9 2 5 9 2 5 9 ... ... 这里的问题是,每列都有一个不同的唯一名称,
~10^3
,y的值是~10^6
矩阵的第一列是ID(整数),其余的是三元组(int8),其中三元组的每个成员都应该有不同的默认值
i、 e.假设默认值为[2,5,9]
我想初始化以下矩阵:
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
0 2 5 9 2 5 9 2 5 9 ...
...
这里的问题是,每列都有一个不同的唯一名称,应该记录该名称
我能想到的初始化矩阵的最快方法是:
default_age = 2
default_height = 5
default_shoe_size = 9
columns = ["id",
"a_age",
"a_height",
"a_shoe_size",
"b_age",
"b_height",
"b_shoe_size",
#...
]
y = len(columns)
x = 10**4
# generate matrix
mat = numpy.zeros(shape=x,
dtype={"names" : columns,
"formats" : ['i'] + ['int8'] * (len(columns) - 1)})
# fill the triplets with default values
for i in xrange(y/3):
j = i * 3
mat[mat.dtype.names[j+1]] = default_age
mat[mat.dtype.names[j+2]] = default_height
mat[mat.dtype.names[j+3]] = default_shoe_size
初始化这样一个矩阵的最快方法是什么
谢谢 您可以使用for循环填写默认值。例如,如果在字典中有默认值:
default_values = {
"a_age": 3,
"a_height": 5,
}
for column, value in default_values.items():
mat[column] = value
您可以使用numpy提供的常规
平铺
和列堆栈
构建数组,然后使用:
其中:
>>> mat
rec.array([(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9)],
dtype=[('id', '<i4'), ('a_age', 'i1'), ('a_height', 'i1'), ('a_shoe_size', 'i1'), ('b_age', 'i1'), ('b_height', 'i1'), ('b_shoe_size', 'i1')])
>>mat
记录数组([(0,2,5,9,2,5,9),(0,2,5,9,2,5,9),(0,2,5,9),(0,2,5,9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9)],
dtype=[('id','这是我对示例的调整,经过调整使其运行
dt=np.dtype({"names": columns, "formats" : ['i'] + ['int8'] * (len(columns) - 1)})
mat=np.zeros((10,),dtype=dt)
for i in range(1,7,3):
mat[dt.names[i]]=default_age
mat[dt.names[i+1]]=default_height
mat[dt.names[i+2]]=default_shoe_size
生产
array([(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9)],
dtype=[('id', '<i4'), ('collections.ChainMap(np.arange(6).reshape(3,2))[0]_age', 'i1'), ('a_height', 'i1'), ('a_shoe_size', 'i1'), ('b_age', 'i1'), ('b_height', 'i1'), ('b_shoe_size', 'i1')])
制作:
array([[2, 5, 9, 2, 5, 9],
[2, 5, 9, 2, 5, 9],
...,
[2, 5, 9, 2, 5, 9]])
添加到id列上
mat1=np.concatenate([np.zeros((x,1),int),mat1],1)
array([[0, 2, 5, 9, 2, 5, 9],
[0, 2, 5, 9, 2, 5, 9],
...
[0, 2, 5, 9, 2, 5, 9],
[0, 2, 5, 9, 2, 5, 9]])
一个新的数据类型-全部为纯“int”:
dt1=np.dtype({"names" : columns, "formats" : ['i'] + ['int'] * (len(columns) - 1)})
mat2=np.empty((x,),dtype=dt1)
如果操作正确,mat1
的数据应该与mat2
的大小和字节顺序相同。在这种情况下,我可以“复制”它(实际上只是更改指针)
mat2
与前面的mat
类似,只是dtype
有点不同(使用i4
而不是i1
字段)
我没有运行时测试,部分原因是我不知道你的x
,y
值是什么样的
或者从中的答案来看,np.ndarray
构造函数可用于使用预先存在的数据缓冲区创建新数组。它仍然需要使用dt1
,即所有i8
dtype
np.ndarray((x,), dt1, mat1)
此外,有关使用视图
v.astype
进行此转换的详细信息。您可以使用枚举来表示列名
class Columns(Enum):
id = 0
a_age = 1
a_height = 2
a_shoe_size = 3
b_age = 4
b_height = 5
b_shoe_size = 6
...
然后使用普通的数组初始化和访问语法,或者任何您想要使用的对象。您可以使用列来代替列索引。例如,a_age
。有关枚举的详细信息,请检查此处是否有理由不只使用数据帧?这里有些可疑。您正在创建一个2-d数组(具有形状(x,len(columns))
),此数组的每个元素本身就是一个具有len(columns)
字段的结构。你确定这是你想要的吗?(我猜你真的想要一维结构化数组。)虽然我还没有理解你的结构描述,但我的经验是,将数据逐字段复制到结构化数组通常是最快的方法。要么这样做,要么列出所有必需的元组。@Warren Weckesser你说得对-我的意思是创建一个1D结构化数组,编辑问题以反映这一点。谢谢!在开始之前关于“最快”,您应该给我们一个工作示例。您没有指定x
或y
,并且您的mat[:,i+1]
索引将不适用于结构化数组。这与我建议的解决方案(性能方面)有何不同?您的解决方案在哪里?这是问题本身。
mat2.data=mat1.data
array([(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9)],
dtype=[('id', '<i4'), ('a_age', '<i4'), ('a_height', '<i4'), ('a_shoe_size', '<i4'), ('b_age', '<i4'), ('b_height', '<i4'), ('b_shoe_size', '<i4')])
np.array([tuple(row) for row in mat1],dtype=dt)
array([(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9), (0, 2, 5, 9, 2, 5, 9),
(0, 2, 5, 9, 2, 5, 9)],
dtype=[('id', '<i4'), ('a_age', 'i1'), ('a_height', 'i1'), ('a_shoe_size', 'i1'), ('b_age', 'i1'), ('b_height', 'i1'), ('b_shoe_size', 'i1')])
np.ndarray((x,), dt1, mat1)
class Columns(Enum):
id = 0
a_age = 1
a_height = 2
a_shoe_size = 3
b_age = 4
b_height = 5
b_shoe_size = 6
...