将名称和格式应用于numpy数组

bzzcjhmw  于 2023-11-18  发布在  其他
关注(0)|答案(2)|浏览(170)

我试图合并两个数组(5000,2)包含整数和(5000,7)包含浮点数。我需要分配名称作为列标题时写入h5,然而,当我试图分配名称和数据类型数组中的每一列得到重复9 times.
代码如下:

namesList = ['EID', 'Domain', 'LAM ID1', 'LAM ID2','LAM ID3', 'LAM ID4', 'LAM ID5', 'LAM ID6', 'LAM ID7']
formatsList = ['int', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float']

ds_dt = np.dtype({'names':namesList, 'formats':formatsList})

Final_Lam_Strength = np.concatenate((LAM_Strength_RFs_Data, LAM_Strength_RFs), axis=1).astype(ds_dt)

字符串
谢谢

wz3gfoph

wz3gfoph1#

直接加载数据到HDF5

如果你的目标是使用h5py将数据加载到HDF5,那么就不需要在另一个数组中复制数据。你可以直接通过创建数据集然后添加数据来完成。下面是我创建的一些简单数据的过程:

namesList = ['EID', 'Domain', 'LAM ID1', 'LAM ID2','LAM ID3', 'LAM ID4', 'LAM ID5', 'LAM ID6', 'LAM ID7']
formatsList = ['int', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float']

ds_dt = np.dtype({'names':namesList, 'formats':formatsList})

# the simple data
nrows, nints, nfloats = 5,2,7
LAM_Strength_RFs_Data = np.arange(nrows*nints).reshape(nrows,nints)
LAM_Strength_RFs = np.arange(nrows*nfloats).reshape(nrows,nfloats)

with h5py.File('SO_77346149.h5', 'w') as h5f:
    ds = h5f.create_dataset('Final_Lam_Strength',shape=(nrows,),dtype=ds_dt)   
    for i in range(nints):
        ds[namesList[i]] = LAM_Strength_RFs_Data[:,i]  
    for i in range(nfloats):   
        ds[namesList[i+2]] = LAM_Strength_RFs[:,i]

字符串

创建NumPy结构化数组

现在,如果你真的需要一个NumPy数组,用np.empty()创建它,用行数定义形状,用ds_dt定义dtype。然后使用命名字段和列引用加载数据。
这继续从上面的例子的数据:

Final_Lam_Strength = np.empty(shape=(nrows,),dtype=ds_dt)
print(Final_Lam_Strength.dtype, Final_Lam_Strength.shape)

for i in range(nints):
    Final_Lam_Strength[namesList[i]] = LAM_Strength_RFs_Data[:,i]

for i in range(nfloats):   
    Final_Lam_Strength[namesList[i+2]] = LAM_Strength_RFs[:,i]

print(Final_Lam_Strength[0]) # first row
print(Final_Lam_Strength[-1]) # last row
print(Final_Lam_Strength['Domain']) # 'Domain' column

创建NumPy记录数组

函数np.core.records.fromarrays在上面的注解中提到过。为了完整起见,这里有一个使用该方法的替代方法。在调用这个函数之前,你不需要创建空数组。

arrayList = [LAM_Strength_RFs_Data[:,0], LAM_Strength_RFs_Data[:,1]] + \
            [LAM_Strength_RFs[:,i] for i in range(nfloats)]
             
Final_Lam_Strength = np.core.records.fromarrays(arrayList, dtype=ds_dt)
print(Final_Lam_Strength.dtype, Final_Lam_Strength.shape)
print(Final_Lam_Strength[0]) # first row
print(Final_Lam_Strength[-1]) # last row
print(Final_Lam_Strength.Domain) # access 'Domain' column by attribute name

结构化数组和记录数组的注意事项

第一个NumPy方法创建一个结构化数组,第二个方法创建一个记录数组。它们类似,但略有不同。记录数组使用点表示法提供对字段(列)的访问。提供示例打印语句以显示差异。此外,np.core.records.fromarrays方法需要中间数据结构这对你的数据来说不是问题,但是如果你有很多数据(比如10E6行和200列),这可能是一个问题。

j2cgzkjk

j2cgzkjk2#

另一个答案中的empty和按字段复制的方法是好的。但是np.lib.recfunctions有一个效用函数,可能会使这更容易。

In [54]: namesList = ['EID', 'Domain', 'LAM ID1', 'LAM ID2','LAM ID3', 'LAM ID4', 'LAM ID5', 'LAM ID6', 'LAM ID7']
    ...: formatsList = ['int', 'int', 'float', 'float', 'float', 'float', 'float', 'float', 'float']
    ...: 
    ...: ds_dt = np.dtype({'names':namesList, 'formats':formatsList})

In [55]: ds_dt
Out[55]: dtype([('EID', '<i4'), ('Domain', '<i4'), ('LAM ID1', '<f8'), ('LAM ID2', '<f8'), ('LAM ID3', '<f8'), ('LAM ID4', '<f8'), ('LAM ID5', '<f8'), ('LAM ID6', '<f8'), ('LAM ID7', '<f8')])

In [56]: ds_dt.fields
Out[56]: 
mappingproxy({'EID': (dtype('int32'), 0),
              'Domain': (dtype('int32'), 4),
              'LAM ID1': (dtype('float64'), 8),
              'LAM ID2': (dtype('float64'), 16),
              'LAM ID3': (dtype('float64'), 24),
              'LAM ID4': (dtype('float64'), 32),
              'LAM ID5': (dtype('float64'), 40),
              'LAM ID6': (dtype('float64'), 48),
              'LAM ID7': (dtype('float64'), 56)})

字符串
所以你有一个有9个字段的dtype,2个int,7个float
concatenate生成一个(n,9)浮点数:

In [57]: arr = np.concatenate((np.ones((3,2),int), np.ones((3,7),float)*2), axis=1)

In [58]: arr
Out[58]: 
array([[1., 1., 2., 2., 2., 2., 2., 2., 2.],
       [1., 1., 2., 2., 2., 2., 2., 2., 2.],
       [1., 1., 2., 2., 2., 2., 2., 2., 2.]])

In [59]: arr.shape
Out[59]: (3, 9)

In [60]: rf
Out[60]: <module 'numpy.lib.recfunctions' from 'C:\\Users\\14256\\miniconda3\\lib\\site-packages\\numpy\\lib\\recfunctions.py'>

In [61]: rf.unstructured_to_structured(arr, ds_dt)
Out[61]: 
array([(1, 1, 2., 2., 2., 2., 2., 2., 2.),
       (1, 1, 2., 2., 2., 2., 2., 2., 2.),
       (1, 1, 2., 2., 2., 2., 2., 2., 2.)],
      dtype=[('EID', '<i4'), ('Domain', '<i4'), ('LAM ID1', '<f8'), ('LAM ID2', '<f8'), ('LAM ID3', '<f8'), ('LAM ID4', '<f8'), ('LAM ID5', '<f8'), ('LAM ID6', '<f8'), ('LAM ID7', '<f8')])


我几乎惊讶于unstructured_to_stuctured工作得如此之好。
这里有一个替代的dtype,它将7个浮点数保持在一起:

In [62]: rf.unstructured_to_structured(arr, [('EID',int),('Domain',int),('LAM', float, 7)])
Out[62]: 
array([(1, 1, [2., 2., 2., 2., 2., 2., 2.]),
       (1, 1, [2., 2., 2., 2., 2., 2., 2.]),
       (1, 1, [2., 2., 2., 2., 2., 2., 2.])],
      dtype=[('EID', '<i4'), ('Domain', '<i4'), ('LAM', '<f8', (7,))])


将名称转换为“列”对于某些目的来说可能很方便,但这会使跨字段工作变得更加尴尬。

相关问题