为numpy数组的每列分配一个dtype

5cnsuln7  于 2023-04-12  发布在  其他
关注(0)|答案(4)|浏览(114)

我尝试为numpy数组的每一列转换dtype,但我没有运气。我尝试了在stackoverflow上找到的一些解决方案(例如使用astype()函数为每一列作为here或尝试显式声明np.array(..., dtype = [])的数据类型作为建议here,但没有任何效果...
特别是对于第二个解决方案,如果我尝试这个代码

with open('posizioni_mm.txt') as f:
    a, b, c, d, e  = [x for x in next(f).split()]
   
    dt = [('A', 'int'), ('B', 'float'), ('C', 'float'), ('D', 'float'), ('E', '<U32')]

    array = np.array([([x for x in line.split()]) for line in f], dtype = dt )

我得到这个错误
ValueError: could not convert string to float: 'link_2'
因为数组被移动了一列('link_2'应该是E列,它的dtype应该是string,但它被放在D列),如果我试图生成没有数据类型的数组,然后生成一个有正确dtype的空数组
array2 = np.zeros(np.shape(array), dtype = dt)
它生成一个数组,每行包含5个元素的5元组

[[(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]
 [(0, 0., 0., 0., '') (0, 0., 0., 0., '') (0, 0., 0., 0., '')
  (0, 0., 0., 0., '') (0, 0., 0., 0., '')]]

怎么了?
编辑:这是文件posizioni_mm.txt的内容

30 0.78 227.31 270.7 link_1
30 0.73 310.79 268.72 link_2
30 0.32 141.41 276.87 link_3
35 0.45 72.47 212.11 link_4
30 0.18 163.22 205.95 link_5
8 0.25 109.69 207.49 link_6
24 0.3 295.15 197.14 link_7
45 0.3 390.97 179.96 link_8
8 0.45 153.08 101.1 link_9
33 0.36 87.44 114.32 link_10
8 0.24 285.9 94.27 link_11
30 0.42 326.87 90.97 link_12
33 0.4 221.15 96.92 link_13
18 0.2 257.49 56.61 link_14
51 0.16 194.71 53.96 link_15
pn9klfpd

pn9klfpd1#

使用numpy.loadtxt从文本文件简单加载数据:

with open('posizioni_mm.txt') as f:
    dt = [('A', 'int'), ('B', 'float'), ('C', 'float'), ('D', 'float'), ('E', '<U32')]
    arr = np.loadtxt(f, dtype=dt)
    print(arr)
[(30, 0.78, 227.31, 270.7 , 'link_1') (30, 0.73, 310.79, 268.72, 'link_2')
 (30, 0.32, 141.41, 276.87, 'link_3') (35, 0.45,  72.47, 212.11, 'link_4')
 (30, 0.18, 163.22, 205.95, 'link_5') ( 8, 0.25, 109.69, 207.49, 'link_6')
 (24, 0.3 , 295.15, 197.14, 'link_7') (45, 0.3 , 390.97, 179.96, 'link_8')
 ( 8, 0.45, 153.08, 101.1 , 'link_9')
 (33, 0.36,  87.44, 114.32, 'link_10')
 ( 8, 0.24, 285.9 ,  94.27, 'link_11')
 (30, 0.42, 326.87,  90.97, 'link_12')
 (33, 0.4 , 221.15,  96.92, 'link_13')
 (18, 0.2 , 257.49,  56.61, 'link_14')
 (51, 0.16, 194.71,  53.96, 'link_15')]

现在您可以通过名称访问列,例如'E'

print(arr['E'])
['link_1' 'link_2' 'link_3' 'link_4' 'link_5' 'link_6' 'link_7' 'link_8'
 'link_9' 'link_10' 'link_11' 'link_12' 'link_13' 'link_14' 'link_15']
6tr1vspr

6tr1vspr2#

一旦你有了数组中的数据,就很容易计算字段(列)的平均值和标准差。这个答案展示了如何扩展@RomanPerekhrest上面发布的解决方案。

f = 'posizioni_mm.txt'
dt = [('A', 'int'), ('B', 'float'), ('C', 'float'), ('D', 'float'), ('E', '<U32')]
arr = np.loadtxt(f, dtype=dt)
col_B = arr['B'] # to load column B values to an array
print(f"Col B mean = {np.mean(col_B):.2f}") # reference col_B above
print(f"Col B stddev = {np.std(arr['B']):.2f}") # Or just use arr['B']

数据的打印值:

Col B mean = 0.37
Col B stddev = 0.18
vulvrdjw

vulvrdjw3#

为了方便复制粘贴,我用一个字符串列表替换你的文件:

In [27]: txt = """30 0.78 227.31 270.7 link_1
    ...: 30 0.73 310.79 268.72 link_2
    ...: 30 0.32 141.41 276.87 link_3
    ...: 35 0.45 72.47 212.11 link_4
    ...: 30 0.18 163.22 205.95 link_5""".splitlines()

您的复合dtype:

In [28]: dt = [('A', 'int'), ('B', 'float'), ('C', 'float'), ('D', 'float'), ('E', '<U32')]

要从数据中创建结构化数组,您需要提供一个元组列表(而不是列表列表)。只需对代码进行微小更改即可:

In [29]: np.array([(tuple([x for x in line.split()])) for line in txt], dtype = dt )
Out[29]: 
array([(30, 0.78, 227.31, 270.7 , 'link_1'),
       (30, 0.73, 310.79, 268.72, 'link_2'),
       (30, 0.32, 141.41, 276.87, 'link_3'),
       (35, 0.45,  72.47, 212.11, 'link_4'),
       (30, 0.18, 163.22, 205.95, 'link_5')],
      dtype=[('A', '<i4'), ('B', '<f8'), ('C', '<f8'), ('D', '<f8'), ('E', '<U32')])

loadtxt/genfromtxt也是一样:

In [30]: data = np.loadtxt(txt,dtype=dt)    
In [31]: data
Out[31]: 
array([(30, 0.78, 227.31, 270.7 , 'link_1'),
       (30, 0.73, 310.79, 268.72, 'link_2'),
       (30, 0.32, 141.41, 276.87, 'link_3'),
       (35, 0.45,  72.47, 212.11, 'link_4'),
       (30, 0.18, 163.22, 205.95, 'link_5')],
      dtype=[('A', '<i4'), ('B', '<f8'), ('C', '<f8'), ('D', '<f8'), ('E', '<U32')])

In [35]: data['A']
Out[35]: array([30, 30, 30, 35, 30])

我不知道你想用组做什么,只要记住结构化数组,你有字段,而不是列,所以二维索引不起作用,你不能,一般来说,跨字段做数学。
可以定义一个dtype,将3个float列组合在一起:

In [36]: dt = [('A', 'int'), ('BCD', 'float',3), ('E', '<U32')]    
In [37]: data = np.loadtxt(txt,dtype=dt)    
In [38]: data
Out[38]: 
array([(30, [7.8000e-01, 2.2731e+02, 2.7070e+02], 'link_1'),
       (30, [7.3000e-01, 3.1079e+02, 2.6872e+02], 'link_2'),
       (30, [3.2000e-01, 1.4141e+02, 2.7687e+02], 'link_3'),
       (35, [4.5000e-01, 7.2470e+01, 2.1211e+02], 'link_4'),
       (30, [1.8000e-01, 1.6322e+02, 2.0595e+02], 'link_5')],
      dtype=[('A', '<i4'), ('BCD', '<f8', (3,)), ('E', '<U32')])        
In [40]: data['BCD']
Out[40]: 
array([[7.8000e-01, 2.2731e+02, 2.7070e+02],
       [7.3000e-01, 3.1079e+02, 2.6872e+02],
       [3.2000e-01, 1.4141e+02, 2.7687e+02],
       [4.5000e-01, 7.2470e+01, 2.1211e+02],
       [1.8000e-01, 1.6322e+02, 2.0595e+02]])

或者将所有数值列加载为float,跳过字符串1。这将得到2d float数组:

In [41]: data = np.genfromtxt(txt,usecols=[0,1,2,3],encoding=None)
In [42]: data
Out[42]: 
array([[3.0000e+01, 7.8000e-01, 2.2731e+02, 2.7070e+02],
       [3.0000e+01, 7.3000e-01, 3.1079e+02, 2.6872e+02],
       [3.0000e+01, 3.2000e-01, 1.4141e+02, 2.7687e+02],
       [3.5000e+01, 4.5000e-01, 7.2470e+01, 2.1211e+02],
       [3.0000e+01, 1.8000e-01, 1.6322e+02, 2.0595e+02]])
ekqde3dh

ekqde3dh4#

谢谢你们,我用一种很不优雅的方式解决了这个问题,但是…它很有效
简而言之,我使用massives.astype(...)方法将字符串(临时)转换为int或float
1.在从文件.txt创建数组后,我使用argsort和astype(int)作为array[:,0]

with open(file) as f:
    
    array = np.array([[x for x in line.split()] for line in f])

array = array[array[:, 0].astype(int).argsort()]

1.然后我对array[:,1]进行操作,使用.astype(float)计算平均值和标准值

groups = np.split(array[:, 0:], np.cumsum(np.unique(array[:, 0].astype(int), return_counts=True)[1])[:-1])
group_stats = np.array([(g[0, 0], len(g), np.mean(g[:, 1].astype(float)).round(2), np.std(g[:, 1].astype(float)).round(2)) for g in groups])

1.然后我使用group_stats来处理其他事情(我必须选择3个累积置信水平〉0.35且标准偏差〈0.2的类)

相关问题