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