【问题标题】:How to convert 2-level nested numpy array to an array如何将 2 级嵌套 numpy 数组转换为数组
【发布时间】:2021-10-22 16:50:46
【问题描述】:

我们正在使用 python dlisio 库从 .dlis 文件(井日志文件)中提取数据。对于大多数公司的文件数据具有相同的结构,但其中一个数据存储在嵌套的 numpy 数组中

正常 dlis 如下所示:

selected_curves_data[0:3]
Output
array([(172600., 1318.3775, 1130.0346, -1130.0301),
       (172590., 1331.5   , 1130.0346, -1130.0301),
       (172580., 1343.5   , 1130.046 , -1130.001 )],
      dtype={'names':['TDEP','A','B','C'], 'formats':['<f4','<f4','<f4','<f4'], 'offsets':[4,8,12,16], 'titles':['T.CHANNEL-I.TDEP','T.CHANNEL-I.A','T.CHANNEL-I.B','T.CHANNEL-C'], 'itemsize':20})

我正在使用的结构不同,每个值都嵌套在两个子列表中,如下所示

selected_curves_data[0:3]
Output
array([([[6860. ]], [[7.887773]], [[65.23707 ]], [[83.41805]], [[98.60489 ]], [[76.93024]], [[305.9046]], [[  1.435147 ]], [[0.]]),
       ([[6859.9]], [[7.594969]], [[65.16657 ]], [[83.31693]], [[98.35259 ]], [[76.18296]], [[305.8163]], [[-10.156202 ]], [[0.]]),
       ([[6859.8]], [[7.539917]], [[65.115074]], [[83.21918]], [[98.084015]], [[75.37859]], [[305.7146]], [[  2.4681084]], [[0.]])],
      dtype={'names':['DEPTH','A','B','C','D','E','F','G','H'], 'formats':[('<f8', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1)),('<f4', (1, 1))], 'offsets':[4,12,16,20,24,62,66,1070,1074], 'titles':['T.CHANNEL-I.DEPTH','T.CHANNEL-I.A','T.CHANNEL-I.B','T.CHANNEL-I.C','T.CHANNEL-I.D','T.CHANNEL-I.E','T.CHANNEL-I.F','T.CHANNEL-I.G','T.CHANNEL-I.H'], 'itemsize':1078}) 

我尝试以下转换为所需的原始结构,但由于原始数据类型为 numpy.dtype[void] 但我的数据类型为 numpy.dtype[float64],因此它不接受处理后的数据

a = np.empty_like (selected_curves_data)
selected_curves_data[0:3]
ithRowList = [] 
i=0
for item in selected_curves_data:
   if i < 3:
       print("Type: ", type(item), " shape: ", item.shape) 
       print("----------------------------- Row ",i, " Original ----------------------------- \n", item)
       #ithRowList = np.empty_like(selected_curves_data)
       for subItem in item:
           ithRowList.append(float(subItem))
       
       print("Type: ", type(ithRowList))
       print("----------------------------- Row ",i, " After ----------------------------- \n", ithRowList)
      
       arr = np.array(ithRowList)
       print("Type: ", type(arr), " shape: ", item.shape) 
       print("----------------------------- Row ",i, " Array ----------------------------- \n", arr)
       print("\n")
      
       np.append(a, ithRowList)
       i+=1
       ithRowList = []
          
       
a[0:3]

输出是

 Type:  <class 'numpy.void'>  shape:  ()
----------------------------- Row  0  Original ----------------------------- 
 ([[6860.]], [[7.887773]], [[65.23707]], [[83.41805]], [[98.60489]], [[76.93024]], [[305.9046]], [[1.435147]], [[0.]])

 Type:  <class 'list'>
----------------------------- Row  0  After ----------------------------- 
 [6860.0, 7.887773036956787, 65.23706817626953, 83.41805267333984, 98.60488891601562, 76.93023681640625, 305.90460205078125, 1.4351470470428467, 0.0]

 Type:  <class 'numpy.ndarray'>  shape:  ()
----------------------------- Row  0  Array ----------------------------- 
 [6.86000000e+03 7.88777304e+00 6.52370682e+01 8.34180527e+01
 9.86048889e+01 7.69302368e+01 3.05904602e+02 1.43514705e+00
 0.00000000e+00]

感谢您的帮助 所以现在它给了我以下错误:

TypeError:DTypes 没有共同的 DType。例如,除非 dtype 为 object,否则它们不能存储在单个数组中。

所以我的目标是得到一个与原始数组结构/维度相同的最终数组,但只包含值,而没有嵌套数组。

所以我希望最终的输出是这样的

(6860., 7.887773, 65.23707, 83.41805, 98.60489,76.93024, 305.9046, 1.435147, 0.)

这是因为将基于此结构进行进一步处理,并且我还希望保留在 numpy 数组中的列详细信息

【问题讨论】:

  • 还有一个问题是值在每一步之后都会发生变化,我想以相同的格式保持相同的原始值并且没有科学记数法
  • np.append 不会就地运行。阅读并重新阅读其文档
  • 第二个数组有更多的字段,每个字段都有一个(1,1)的形状。我会构造一个新的 dtype,它具有必需的字段,但具有与第一个一样的字段规范。逐个字段复制值。

标签: python arrays numpy multidimensional-array


【解决方案1】:

要从 dtype 的第 2 种样式复制到第 1 种样式 - 制作一个目标,然后逐个字段复制。

In [287]: dt1 = np.dtype([('A','f4'),('B','f4')])
In [288]: dt2 = np.dtype([('A','f4',(1,1)),('B','f4',(1,1))])

创建一个类型 2 的数组:

In [290]: x=np.zeros(3, dt2)
In [291]: x['A']=[[[1]],[[.2]],[[100]]]; x['B']=[[[.0]],[[2]],[[200]]]
In [292]: x
Out[292]: 
array([([[  1. ]], [[  0.]]), ([[  0.2]], [[  2.]]),
       ([[100. ]], [[200.]])],
      dtype=[('A', '<f4', (1, 1)), ('B', '<f4', (1, 1))])

目标和副本:

In [293]: y = np.zeros(x.shape, dt1)
In [294]: for name in dt2.names:
     ...:     y[name]=np.squeeze(x[name])
     ...: 
In [295]: y
Out[295]: 
array([(  1. ,   0.), (  0.2,   2.), (100. , 200.)],
      dtype=[('A', '<f4'), ('B', '<f4')])

我不得不使用 squeeze,因为 x 的元素具有形状 (3,1,1),而在 y 中它们是 (3,)

【讨论】:

  • 非常感谢 hpaulj 的回答。但在我的情况下,我有数千条记录和列名,如果不对列名“A”、“B”和值进行硬编码,我怎么能动态地做到这一点?
  • 我可以想象改变formats 的值。它是一个元组列表,需要是一个不同元组的列表。
  • 非常感谢 hpaulj!这解决了我的问题。我还编写了创建动态 dtype 的代码,我会尽快发布它
猜你喜欢
  • 2018-12-24
  • 1970-01-01
  • 2018-12-20
  • 2018-12-06
  • 1970-01-01
  • 2021-12-18
  • 2021-07-21
  • 2017-11-15
  • 1970-01-01
相关资源
最近更新 更多