#!/usr/bin/env python # coding: utf-8 # # Write 3D data into ASCII (text) file with metadata # # ## Как записать 3D данные в текстовый формат "аля" фортран # # **Автор: Шабанов П.А.** # # **E-mail: pa.shabanov@gmail.com** # # **Blog: geofortran.blogspot.com** # # 22:24 11.06.2015 # # ### Аннотация # # --------------- # # Бывает, что коллеги просят дать им данные, с которыми ты работаешь. И, как это часто бывает в российской науке, они просят их в текстовом формате. Хотя ты работаешь, скажем, с netcdf. Но вот ещё незадача: формат нужен особый! Нужно, чтобы матрицы лежали блоками, а разделителями этих блоков должны быть даты (скажем, "год месяц день"), по которым можно установить временной срез блока. И так как ты - молодой и смелый, то кто, как не ты можешь решить эту задачу! # # Если серьёзно, то бывает нужно записать данные из матрицы, но при этом "накидать шапку" в файл. Функция np.savetxt здесь, вроде, не особо помогает. Но есть трюк, который легко и непринуждённо справляется с поставленной задачей. Этот трюк - использование конструкции "with". # # В python версии 2.5 и выше, файловый объект дополнен методами __enter__ и __exit__. Первый метод просто возвращает файловый объект, а второй закрывает его. # # --------------- # # ### Электронные ресурсы # # 1. [Understanding Python's "with" statement](http://effbot.org/zone/python-with-statement.htm) # In[ ]: f = open("x.txt", 'w') print (f) print (f.__enter__()) f.write('1') print (f.__exit__(None, None, None)) f.write('2') # Приведённый выше код можно заменить на более элегантную конструкцию: # In[11]: with open("x.txt") as f: data = f.read() print data # А теперь перейдём к матрицам и 3D массивам # In[14]: import numpy as np x = np.random.random((12, 10, 7)) ss = [] for i in xrange(12): ss.append(' %d %d\n' % (2015, i+1)) print ss with file('testfile.txt', 'w') as outfile: for i, data_slice in enumerate(x): outfile.write(ss[i]) np.savetxt(outfile, data_slice, fmt='%9.3f') В результате работы данной программы файл testfile.txt выглядит примерно так: 2015 1 0.121 0.973 0.818 0.273 0.612 0.424 0.817 0.301 0.611 0.448 0.746 0.091 0.986 0.482 0.895 0.134 0.866 0.004 0.572 0.887 0.855 0.794 0.281 0.100 0.905 0.613 0.780 0.514 0.489 0.633 0.447 0.898 0.299 0.880 0.400 0.549 0.515 0.305 0.857 0.764 0.945 0.129 0.433 0.640 0.249 0.717 0.010 0.381 0.104 0.639 0.840 0.315 0.809 0.704 0.430 0.359 0.297 0.346 0.563 0.762 0.521 0.822 0.403 0.297 0.334 0.418 0.005 0.199 0.280 0.212 2015 2 0.738 0.115 0.780 0.228 0.229 0.209 0.604 0.099 0.709 0.291 0.804 0.683 0.791 0.137 0.353 0.459 0.368 0.958 0.329 0.518 0.911 0.207 0.819 0.636 0.089 0.872 0.412 0.799 0.324 0.283 0.758 0.572 0.165 0.959 0.010 0.013 0.046 0.776 0.396 0.085 0.026 0.301 0.498 0.651 0.008 0.911 0.528 0.594 0.354 0.516 0.344 0.353 0.130 0.670 0.144 0.950 0.918 0.210 0.681 0.684 0.224 0.147 0.849 0.367 0.559 0.614 0.152 0.423 0.135 0.160 *** 2015 12 0.023 0.982 0.738 0.416 0.886 0.199 0.896 0.220 0.266 0.530 0.133 0.592 0.119 0.529 0.318 0.432 0.933 0.913 0.135 0.313 0.629 0.079 0.068 0.261 0.918 0.731 0.577 0.222 0.806 0.063 0.560 0.351 0.703 0.479 0.707 0.220 0.782 0.354 0.568 0.216 0.388 0.003 0.499 0.753 0.101 0.403 0.975 0.863 0.277 0.785 0.231 0.013 0.091 0.471 0.745 0.114 0.972 0.319 0.125 0.130 0.635 0.512 0.787 0.916 0.374 0.719 0.388 0.344 0.714 0.301 # Таким образом, первая ось (axis0=12) 3D массива x - это число блоков; вторая ось (axis1=10) - число строк в блоке; и третья ось (axis2=7) - число столбцов в блоке. Между блоками мы сформировали строки метаданных (год и месяц в нашем случае). Numpy функция savetxt позволяет задать формат представления данных. В результате у вас из случайной матрицы вышел текстовый файл с упаковкой "аля" фортран.