我问这个问题的主要原因是因为我不完全知道结构化数组与正常数组相比是如何工作的,因为我找不到适合我的案例。而且,我可能首先错误地填充了我的结构化数组。PYTHON/NUMPY:处理与普通numpy数组相比较的结构化数组Python2.7
所以,在这里,我想提出'普通'numpy阵列版本(以及我需要做的)和新的'结构化'阵列版本。我的(最大的)数据集包含大约200e6个对象/行,最多40-50个属性/列。它们都有相同的数据类型,除了一些特殊的列:'haloid','hostid','type'。他们是身份证号码或国旗,我必须保留其余的数据,因为我必须与他们识别我的对象。
数据集名:
data_array: ndarray shape: (42648, 10)
数据类型:从.hdf5文件格式
dt = [('haloid', '<u8'), ('hostid', '<u8'), ('type', 'i1'),
('mstar', '<f8'), ('x_pos', '<f8'), ('y_pos', '<f8'),
('z_pos', '<f8'), ('x_vel', '<f8'), ('y_vel', '<f8'), ('z_vel', '<f8')]
读数据到阵列
大部分数据被存储在hdf5-文件(它们中的2000个对应于我必须一次处理的一个快照),其应该被读入到单个阵列中
import numpy as np
import h5py as hdf5
mydict={'name0': 'haloid', 'name1': 'hostid', ...} #dictionary of column names
nr_rows = 200000 # approximated
nr_files = 100 # up to 2200
nr_entries = 10 # up to 50
size = 0
size_before = 0
new_size = 0
# normal array:
data_array=np.zeros((nr_rows, nr_entries), dtype=np.float64)
# structured array:
data_array=np.zeros((nr_rows,), dtype=dt)
i=0
while i<nr_files:
size_before=new_size
f = hdf5.File(path, "r")
size=f[mydict['name0']].size
new_size+=size
a=0
while a<nr_entries:
name=mydict['name'+str(a)]
# normal array:
data_array[size_before:new_size, a] = f[name]
# structured array:
data_array[name][size_before:new_size] = f[name]
a+=1
i+=1
编辑:我修改上面的代码,因为hpaulj是幸运的评论如下:混乱的
第一点。您显示一个名称为
dt = [('haloid', '<u8'), ('hostid', '<u8'), ('type', 'i1'),....
的dt定义,但是 的h5加载为 data_array ['name'+ str(a)] [size_before:new_size] = f ['name'+ str(a)]换句话说,文件具有名称类似name0,name1, 的数据集,并且您将这些数据集下载到数组中,其名称相同的 。
这是一个 'I-简化代码' 复制/粘贴错误,我纠正它!
问题1:这是填补结构化数组的正确方法吗?
data_array[name][size_before:new_size] = f[name]
问题2:如何解决结构化阵列列?
data_array[name] #--> column with a certain name
问题3:如何解决在结构数组一整行?
data_array[0] #--> first row
问题4:如何解决3行中的所有列?
# normal array:
print data_array[0:3,:]
[[ 1.21080866e+10 1.21080866e+10 0.00000000e+00 5.69363234e+08
1.28992369e+03 1.28894614e+03 1.32171442e+03 -1.08210000e+02
4.92900000e+02 6.50400000e+01]
[ 1.21080711e+10 1.21080711e+10 0.00000000e+00 4.76329837e+06
1.29058079e+03 1.28741361e+03 1.32358059e+03 -4.23130000e+02
5.08720000e+02 -6.74800000e+01]
[ 1.21080700e+10 1.21080700e+10 0.00000000e+00 2.22978043e+10
1.28750287e+03 1.28864306e+03 1.32270418e+03 -6.13760000e+02
2.19530000e+02 -2.28980000e+02]]
# structured array:
print data_array[0:3]
#it returns a lot of data ...
[[ (12108086595L, 12108086595L, 0, 105676938.02998888, 463686295.4907876,.7144191943337, -108.21, 492.9, 65.04)
(12108071103L, 12108071103L, 0, 0.0, ... more data ...
... 228.02) ... more data ...
(8394715323L, 8394715323L, 2, 0.0, 823505.2374262045, 0798, 812.0612163877823, -541.61, 544.44, 421.08)]]
问题5:为什么data_array[0:3]
不仅返回第3行与10列?
问题6:如何解决第一列中的前两个元素?
# normal array:
print data_array[0:1,0]
[ 1.21080866e+10 1.21080711e+10]
# structured array:
print data_array['haloid']][0][0:1]
[12108086595 12108071103]
行!我明白了!
问题7:如何通过名称解决三个特定的列,他们在该列的前3行?
# normal array:
print data_array[0:3, [0,2,1]]
[[ 1.21080866e+10 0.00000000e+00 1.21080866e+10]
[ 1.21080711e+10 0.00000000e+00 1.21080711e+10]
[ 1.21080700e+10 0.00000000e+00 1.21080700e+10]]
# structured array:
print data_array[['haloid','type','hostid']][0][0:3]
[(12108086595L, 0, 12108086595L) (12108071103L, 0, 12108071103L)
(12108069992L, 0, 12108069992L)]
好的,最后一个例子似乎工作!
问题8:之间有什么区别:
(一)data_array['haloid'][0][0:3]
和(b)data_array['haloid'][0:3]
其中(一)返回真前三haloids和(b)返回了很多卤素(10x3)。
[[12108086595 12108071103 12108069992 12108076356 12108075899 12108066340
9248632230 12108066342 10878169355 10077026070]
[ 6093565531 10077025463 8046772253 7871669276 5558161476 5558161473
12108068704 12108068708 12108077435 12108066338]
[ 8739142199 12108069995 12108069994 12108076355 12108092590 12108066312
12108075900 9248643751 6630111058 12108074389]]
问题9:什么是data_array['haloid'][0:3]
实际上返回?
问题10:如何屏蔽结构阵列np.where()
# NOTE: col0,1,2 are some integer values of the column I want to address
# col_name0,1,2 are corresponding names e.g. mstar, type, haloid
# normal array
mask = np.where(data[:,col2] > data[:,col1])
data[mask[:][0]]
mask = np.where(data[:,col2]==2)
data[:,col0][[mask[:][0]]]=data[:,col2][[mask[:][0]]]
#structured array
mask = np.where(data['x_pos'][0] > data['y_pos'][0]])
data[mask[:][0]]
mask = np.where(data[:,col2]==2)
data['haloid'][:,col0][[mask[:][0]]]=data['hostid'][:,col1][[mask[:][0]]]
这似乎是工作,但我不知道!
问题11:我还可以使用np.resize()
,如:data_array = np.resize(data_array,(new_size, nr_entries))
到调整大小/重塑我的阵列?
问题12:如何排序结构化数组?
# normal array:
data_sorted = data[np.argsort(data[:,col2])]
# structured array:
data_sorted = data[np.argsort(data['mstar'][:,col3])]
谢谢,我感谢任何帮助或建议!
X [0] [0:3]从行0返回前三列。 X [0:3]返回前三行的所有列 – valentin
@valentin:嗨,感谢您的评论!我不确定,当我打印data_array ['haloid'] [0:3]时,我得到(3,10),但所有列,但只有'卤素的回报(不知道他们来自哪里!)。请再次看到问题,我添加了data_array ['haloid'] [0:3]的输出。 – firefly2517
我只是剔除了你的问题,但我想知道为什么不能将id值保存为相同长度的单独数组?将1d数组作为一个字段搜索一样简单。它是否有助于尝试一个小例子,并且没有'h5py'部分?如果我写回答,将会用一个非常小的例子来说明。 – hpaulj