С помощью copy-n-paste вашего файла примера:
In [208]: data = np.genfromtxt('stack59761369.csv',encoding=None,dtype=None,names=True)
In [209]: data
Out[209]:
array([('15:09:11.8', '-34:13:44.9'), ('09:19:46.8', '+33:44:58.452'),
('05:15:43.488', '+19:21:46.692'),
('04:19:12.096', '+55:52:43.32')],
dtype=[('ra', '<U12'), ('dec', '<U13')])
с этим dtype и именами я получаю структурированный массив, 1d, с 2 полями.
In [210]: data['ra']
Out[210]:
array(['15:09:11.8', '09:19:46.8', '05:15:43.488', '04:19:12.096'],
dtype='<U12')
In [211]: np.char.split(data['ra'],':')
Out[211]:
array([list(['15', '09', '11.8']), list(['09', '19', '46.8']),
list(['05', '15', '43.488']), list(['04', '19', '12.096'])],
dtype=object)
это разделение дает массив dtype объекта со списками. Они могут быть объединены в один двумерный массив с помощью vstack
:
In [212]: np.vstack(np.char.split(data['ra'],':'))
Out[212]:
array([['15', '09', '11.8'],
['09', '19', '46.8'],
['05', '15', '43.488'],
['04', '19', '12.096']], dtype='<U6')
и преобразованы в числа с плавающей точкой:
In [213]: np.vstack(np.char.split(data['ra'],':')).astype(float)
Out[213]:
array([[15. , 9. , 11.8 ],
[ 9. , 19. , 46.8 ],
[ 5. , 15. , 43.488],
[ 4. , 19. , 12.096]])
In [214]: np.vstack(np.char.split(data['dec'],':')).astype(float)
Out[214]:
array([[-34. , 13. , 44.9 ],
[ 33. , 44. , 58.452],
[ 19. , 21. , 46.692],
[ 55. , 52. , 43.32 ]])
pandas
In [256]: df = pd.read_csv('stack59761369.csv',delim_whitespace=True)
In [257]: df
Out[257]:
ra dec
0 15:09:11.8 -34:13:44.9
1 09:19:46.8 +33:44:58.452
2 05:15:43.488 +19:21:46.692
3 04:19:12.096 +55:52:43.32
In [258]: df['ra'].str.split(':',expand=True).astype(float)
Out[258]:
0 1 2
0 15.0 9.0 11.800
1 9.0 19.0 46.800
2 5.0 15.0 43.488
3 4.0 19.0 12.096
In [259]: df['dec'].str.split(':',expand=True).astype(float)
Out[259]:
0 1 2
0 -34.0 13.0 44.900
1 33.0 44.0 58.452
2 19.0 21.0 46.692
3 55.0 52.0 43.320
direct чтение строки
In [279]: lines = []
In [280]: with open('stack59761369.csv') as f:
...: header=f.readline()
...: for row in f:
...: alist = row.split()
...: alist = [[float(i) for i in astr.split(':')] for astr in alist]
...: lines.append(alist)
...:
In [281]: lines
Out[281]:
[[[15.0, 9.0, 11.8], [-34.0, 13.0, 44.9]],
[[9.0, 19.0, 46.8], [33.0, 44.0, 58.452]],
[[5.0, 15.0, 43.488], [19.0, 21.0, 46.692]],
[[4.0, 19.0, 12.096], [55.0, 52.0, 43.32]]]
In [282]: np.array(lines)
Out[282]:
array([[[ 15. , 9. , 11.8 ],
[-34. , 13. , 44.9 ]],
[[ 9. , 19. , 46.8 ],
[ 33. , 44. , 58.452]],
[[ 5. , 15. , 43.488],
[ 19. , 21. , 46.692]],
[[ 4. , 19. , 12.096],
[ 55. , 52. , 43.32 ]]])
In [283]: _.shape
Out[283]: (4, 2, 3)
Первое измерение - количество строк; второй 2 столбца, третий 3 значения в столбце
преобразование в градус
In [285]: _282@[1,1/60,1/360]
Out[285]:
array([[ 15.18277778, -33.65861111],
[ 9.44666667, 33.8957 ],
[ 5.3708 , 19.4797 ],
[ 4.35026667, 55.987 ]])
упс, значение -34 градуса неверно; все члены элемента должны иметь одинаковый знак.
коррекция
Идентифицировать элементы с отрицательной степенью:
In [296]: mask = np.sign(_282[:,:,0])
In [297]: mask
Out[297]:
array([[ 1., -1.],
[ 1., 1.],
[ 1., 1.],
[ 1., 1.]])
настроить все 3 условия соответственно:
In [298]: x = np.abs(_282)*mask[:,:,None]
In [299]: x
Out[299]:
array([[[ 15. , 9. , 11.8 ],
[-34. , -13. , -44.9 ]],
[[ 9. , 19. , 46.8 ],
[ 33. , 44. , 58.452]],
[[ 5. , 15. , 43.488],
[ 19. , 21. , 46.692]],
[[ 4. , 19. , 12.096],
[ 55. , 52. , 43.32 ]]])
In [300]: x@[1, 1/60, 1/360]
Out[300]:
array([[ 15.18277778, -34.34138889],
[ 9.44666667, 33.8957 ],
[ 5.3708 , 19.4797 ],
[ 4.35026667, 55.987 ]])