Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I want to create a numpy array (size ~65000 rows x 17 columns). The first column contains complex numbers and the rest contains unsigned integers.

I first create a numpy.zeros array of the desired size and after that I want to fill it with complex numbers and uints as described above. I have looked at the dtypes option and therein should lie the solution I think, but I can't get it to work.

After that I want to save the whole array to a text file as CSV as follows:

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

etc...

I tried this amongst others, but later it gives me the following error:

TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and '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
share|improve this question
3  
Please include your code. –  Ffisegydd Jan 9 at 10:57
    
The data type is now a "row" in itself, so you need only fields = numpy.zeros(2**m, dtype=dt). –  Psirus Jan 9 at 11:14
    
In the for loop it then gives me the following error: IndexError: too many indices –  Gordian Jan 9 at 11:17
    
Your fields is now 2d, with 17 columns, and each element has 17 fields. That's 17x bigger than what you probably want. –  hpaulj Jan 9 at 18:20

2 Answers 2

Maybe this does what you want:

Edit: Flattened the structure, so it is now closer to what you originally had in mind, and you can save it using 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)

Note: the array is now basically a vector of elements of the type dt. You can access the complex number with fields[row][0], and fields[row][1] will return the "subarray" of integers. That means to change a specific integer, you'll need to do something like this: fields[row][1][5] = 7.

share|improve this answer
1  
You don't need to iterate over the rows. Vector operations work WITHIN each field: fields['comp'] += 1j and fields['f']=np.arange(15) –  hpaulj Jan 9 at 18:23
    
Is there a way of writing this dtype to a file (with savetxt) without the brackets? fmt='%f %s' works but prints the f field as a list. –  hpaulj Jan 10 at 3:27
    
That is my next step as well, I can't figure out how to do it... –  Gordian Jan 10 at 12:43
    
A np.complex field displayed with %s produces (2+1j). That's good if you like the (), but awkward if you don't. –  hpaulj Jan 11 at 20:51

np.savetxt does not handle fields with different number of values very well. A complex field has 2 values per row, an int just one. Or 15 in Psirus's version.

The basic operation in savetxt is:

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

But the row tuple for your dtype is something like (for just 2 int fields)

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

And for Psirus's dtype:

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

It's hard to come up with a format string that works without resorting to a generic %s for at least the complex value. It is harder still to come up with one that passes savetxt error checking.

It may be best to write your own save routine, one that formats that tuple exactly as you want it.

The savetxt code is readily available to read and copy. The asbyte business is for Python3 compatibility.

It might easier to skip the complex dtype, and work with a plain 2d array, Here's a simple example of writing a complex 'field' plus a couple of ints, without resorting to a structured dtype. The 'complex' magic resides in the fmt string.

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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.