【问题标题】:Python create numpy array with different dtypesPython创建具有不同dtypes的numpy数组
【发布时间】:2015-01-09 10:56:53
【问题描述】:

我想创建一个numpy 数组(大小约为 65000 行 x 17 列)。第一列包含复数,其余包含无符号整数。

我首先创建一个所需大小的numpy.zeros 数组,然后我想用上面描述的复数和 uint 填充它。我查看了dtypes 选项,其中应该是我认为的解决方案,但我无法让它工作。

之后,我想将整个数组保存为 CSV 格式的文本文件,如下所示:

0.25+0.30j,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1

0.30+0.40j,0,1,0,0,0,0,0,0,1,0,1,1,1,1,1,1

等等……

我试过这个,但后来它给了我以下错误:

TypeError: +: 'numpy.ndarray' 和不支持的操作数类型 'numpy.ndarray'

m = 16

dt = numpy.dtype([('comp', numpy.complex), ('f0', numpy.int64), ('f1', numpy.int64),
    ('f2', numpy.int64), ('f3', numpy.int64), ('f4', numpy.int64), ('f5', numpy.int64),
    ('f6', numpy.int64), ('f7', numpy.int64), ('f8', numpy.int64), ('f9', numpy.int64),
    ('f10', numpy.int64), ('f11', numpy.int64), ('f12', numpy.int64), ('f13', numpy.int64),
    ('f14', numpy.int64), ('f15', numpy.int64)])

fields = numpy.zeros((2**m, m+1), dtype=dt)

for i in range(0, m):
    fields[:,0] = fields[:,0] + 1 # for example I add only 1 here

【问题讨论】:

  • 请附上您的代码。
  • 数据类型现在本身就是一个“行”,所以你只需要fields = numpy.zeros(2**m, dtype=dt)
  • 在 for 循环中它给了我以下错误:IndexError: too many indices
  • 您的fields 现在是 2d,有 17 列,每个元素有 17 个字段。这比您可能想要的要大 17 倍。

标签: python arrays numpy complex-numbers


【解决方案1】:

也许这就是你想要的:

编辑:扁平化结构,现在它更接近您最初的想法,您可以使用savetxt 保存它。

import numpy

m = 15
rows = 5

integers = [('f'+str(i), numpy.int64) for i in range(m)]
dt = numpy.dtype([('comp', numpy.complex)] + integers)
fields = numpy.zeros(rows, dtype=dt)

fields['comp'] += 1j
fmt = '%s ' + m*' %u'
numpy.savetxt('fields.txt', fields, fmt=fmt)

注意:数组现在基本上是dt 类型元素的向量。 您可以使用fields[row][0] 访问复数,fields[row][1] 将返回整数的“子数组”。这意味着要更改特定整数,您需要执行以下操作:fields[row][1][5] = 7

【讨论】:

  • 您不需要遍历行。向量运算在每个字段中起作用:fields['comp'] += 1jfields['f']=np.arange(15)
  • 有没有办法在没有括号的情况下将此 dtype 写入文件(使用savetxt)? fmt='%f %s' 有效,但将 f 字段打印为列表。
  • %s 一起显示的np.complex 字段生成(2+1j)。如果你喜欢(),那很好,但如果你不喜欢,那就尴尬了。
【解决方案2】:

np.savetxt 不能很好地处理具有不同数量值的字段。复杂字段每行有 2 个值,一个 int 值只有一个。或 Psirus 版本中的 15 个。

savetxt中的基本操作是:

for row in X:
   fh.write(asbytes(format % tuple(row) + newline))

但是您的 dtype 的行 tuple 类似于(仅适用于 2 个 int 字段)

In [306]: tuple(X[1])
Out[306]: ((1+4j), 0, 0)

对于 Psirus 的 dtype:

In [307]: tuple(fields[1])
Out[307]: ((1+4j), array([2, 3], dtype=int64))

如果不使用通用 %s 至少对于复杂值,很难想出一个可以工作的格式字符串。想出一个通过savetxt 错误检查的方法更难。

最好编写自己的save 例程,该例程可以完全按照您的需要格式化该元组。

savetxt 代码易于阅读和复制。 asbyte 业务是为了兼容 Python3。

跳过复杂的 dtype 并使用普通的 2d 数组可能更容易,这是一个简单的示例,它编写了一个复杂的“字段”加上几个 int,而不使用结构化的 dtype。 “复杂”的魔力存在于 fmt 字符串中。

In [320]: Y = np.zeros((5,4),dtype=int)
In [321]: Y[:,0]=np.arange(5)
In [322]: Y[:,1]=np.arange(5,0,-1)
In [323]: Y[:,2]=np.arange(5,0,-1)
In [324]: Y[:,3]=np.arange(10,15)

In [325]: Y
Out[325]: 
array([[ 0,  5,  5, 10],
       [ 1,  4,  4, 11],
       [ 2,  3,  3, 12],
       [ 3,  2,  2, 13],
       [ 4,  1,  1, 14]])

In [326]: np.savetxt('mypy/temp.txt',Y,fmt='%3d+%dj, %3d, %3d')

In [327]: cat mypy/temp.txt
  0+5j,   5,  10
  1+4j,   4,  11
  2+3j,   3,  12
  3+2j,   2,  13
  4+1j,   1,  14

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 2017-12-07
    • 2015-08-24
    • 1970-01-01
    • 2015-11-25
    • 2022-11-03
    • 2018-04-06
    相关资源
    最近更新 更多