This script:
import numpy as np
txt = b"""7
9 -0.4330127018930699 0.2499999999985268 1.0
10 -0.1366025403783193 -0.03660254037890862 1.0
11 -0.2499999999985268 -0.4330127018930699 1.0
12 0.03660254037890862 -0.1366025403783193 1.0
13 0.4330127018930699 -0.2499999999985268 1.0
14 0.1366025403783193 0.03660254037890862 1.0
15 0.2499999999985268 0.4330127018930699 1.0
[...] # some more data, other format
"""
dt = np.dtype([('idx', int, 1), ('vals', float, 3)])
#dt = np.dtype('i,f,f,f')
print(dt)
def gentxt(txt, dt):
f = txt.splitlines()
line = f[0]
num_nodes = int(line)
aslice = slice(1,num_nodes+1)
# print(f[aslice])
points = np.genfromtxt(
f[aslice],
dtype=dt)
return points
M = gentxt(txt,dt)
print(repr(M))
produces
1304:~/mypy$ python3 stack33406545.py
[('idx', '<i4'), ('vals', '<f8', (3,))]
array([(9, [-0.4330127018930699, 0.2499999999985268, 1.0]),
(10, [-0.1366025403783193, -0.03660254037890862, 1.0]),
(11, [-0.2499999999985268, -0.4330127018930699, 1.0]),
(12, [0.03660254037890862, -0.1366025403783193, 1.0]),
(13, [0.4330127018930699, -0.2499999999985268, 1.0]),
(14, [0.1366025403783193, 0.03660254037890862, 1.0]),
(15, [0.2499999999985268, 0.4330127018930699, 1.0])],
dtype=[('idx', '<i4'), ('vals', '<f8', (3,))])
I used simple slicing of a list of text lines. I tried to use islice
as you do, but decided it wasn't worth my time to get it right. The central thing is to use an interable that produces the desired text lines. It doesn't matter whether it's a list, a range of file lines, or the output of a generator.
fromiter
is picky about what it accepts. It must produce a 1d array;
A list or iterable that returns individual strings (convertable to a simple dtype) work:
In [233]: np.fromiter(['1', '2', '3', '4'],dtype=int)
Out[233]: array([1, 2, 3, 4])
but a list of lists (2d) does not:
In [234]: np.fromiter([['1', '2'],['3', '4']],dtype=int)
....
ValueError: setting an array element with a sequence.
with a complex dtype I have to give it tuples:
In [236]: np.fromiter([('1', '2'),('3', '4')],dtype=np.dtype('i,i'))
Out[236]:
array([(1, 2), (3, 4)], dtype=[('f0', '<i4'), ('f1', '<i4')])
Strings or tuples of strings with several numbers doesn't work,['1 2','3 4']
, [('1 2',),('3 4',)]
. genfromtxt
is much better handling text with rows and columns (csv like).