Résumé relatif aux E / S de python et fortran

introduction

En ce qui concerne l'entrée et la sortie de python <-> fortran, il est difficile de trouver une description cohérente sur Internet, j'ai donc décidé de la résumer pour autant que je sache.

En passant, «np.savez» et «np.load» sont recommandés pour l'entrée / sortie de données entre les pythons.

Lire la sortie python avec fortran

Comment utiliser numpy

Données de sortie selon la procédure suivante

  1. Préparez un tableau numpy
  2. Convertissez pour adapter fortran avec reshape
  3. Convertir en binaire avec ʻas type`
  4. Sortie avec tofile

Exemple de code python qui produit des nombres réels 3D double précision avec petit boutien

import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx))
a.reshape([ix*jx*kx],order='F').astype(endian+'d').tofile('test.dat')

Pour lire ceci avec fortran, procédez comme suit. Supposons que l'ordinateur que vous utilisez soit un peu endian. ʻOpen dans fortran requiert ʻaccess = 'stream'

program test
  implicit none

  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a

  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  read(idf) a
  close(idf)
  
  stop
end program test

Si vous souhaitez échanger des données big endian, utilisez du code python

endian='>'

Vous pouvez le changer en. Cette variable ʻendian contrôle comment convertir en binaire avec ʻas type

Dans le code fortran

  open(newunit=idf, file='test.dat',form='unformatted',access='stream',convert='big_endian')

Et. Si vous voulez sortir / entrer avec une précision unique, réécrivez le code python comme suit

import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx),dtype=np.float32)
a.reshape([ix*jx*kx],order='F').astype(endian+'f').tofile('test.dat')

Modification des parties de np.ones et de ʻas type` pour gérer la simple précision.

Le code fortran correspondant ressemble à ceci:

program test
  implicit none

  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.e0)), dimension(ix,jx,kx) :: a

  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  read(idf) a
  close(idf)
  
  stop
end program test

Seule la partie de real (KIND (0.e0)) a été modifiée.

Si vous souhaitez générer plusieurs tableaux dans un fichier, suivez les étapes ci-dessous.

  1. Combinez plusieurs tableaux avec np.array
  2. Utilisez reshape pour créer un tableau unidimensionnel.
  3. Échangez les positions d'index avec «T».
import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx),dtype=np.float32)
b = np.ones((ix,jx,kx),dtype=np.float32)*2
c = np.ones((ix,jx,kx),dtype=np.float32)*3
np.array([a,b,c]).T.reshape([3*ix*jx*kx],order='F').astype(endian+'f').tofile('test.dat')

Le code fortran à lire est

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.e0)), dimension(ix,jx,kx) :: a,b,c

  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  read(idf) a,b,c
  close(idf)
  
  stop
end program test

Devrait être

D'autre part, lors de la sortie de tableaux de tailles différentes

  1. Utilisez reshape pour créer un tableau unidimensionnel
  2. Utilisez np.concatenate pour organiser le tableau Il vous suffit de suivre la procédure
Le code python ressemble à ceci

import numpy as np

ix, jx, kx = 3, 4, 5
lx, mx = 2, 4
endian='<'
a = np.ones((ix,jx,kx))
b = np.ones((lx,mx))*2

a1 = a.reshape([ix*jx*kx],order='F')
b1 = b.reshape([lx*mx],order='F')
np.concatenate([a1,b1]).astype(endian+'d').tofile('test.dat')

Lors de la lecture de fortran, c'est la même chose qu'avant, mais procédez comme suit.

program test
  implicit none

  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  integer, parameter :: lx = 2, mx = 4
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a
  real(KIND(0.d0)), dimension(lx,mx) :: b

  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  read(idf) a,b
  close(idf)
  
  stop
end program test

Comment utiliser scipy.io.FortranFile

La méthode ci-dessus est plus simple pour le code python, mais si vous n'utilisez pas ʻaccess = 'stream'dans fortran, vous devrez éditer vous-même l'en-tête de données. C'estscipy.io.FortranFile` qui ajuste bien cette partie.

Le code Python ressemble à ceci

import numpy as np
from scipy.io import FortranFile

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx))
f = FortranFile('test.dat','w')
f.write_record(a)
f.close()

Le code Fortran pour la lecture est

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a

  open(newunit=idf, file='test.dat',form='unformatted')
  read(idf) a
  close(idf)
  
  stop
end program test

Ca devrait être fait.

La sortie de plusieurs tableaux est plus facile que d'utiliser Numpy

a = np.ones((ix,jx,kx))
b = np.ones((ix,jx,kx))*2
f = FortranFile('test.dat','w')
f.write_record(a,b)
f.close()

Et ajoutez-le simplement à l'argument de write_record. Code de lecture Fortran

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a,b

  open(newunit=idf, file='test.dat',form='unformatted')
  read(idf) a,b
  close(idf)
  
  stop
end program test

Tout ce que vous avez à faire est de disposer les tableaux côte à côte.

Cependant, si vous regardez le site Web scipy

Since this is a non-standard file format, whose contents depend on the compiler and the endianness of the machine, caution is advised. Files from gfortran 4.8.0 and gfortran 4.1.2 on x86_64 are known to work.

Consider using Fortran direct-access files or files from the newer Stream I/O, which can be easily read by numpy.fromfile.

c'est écrit comme ça. Le format fortran semble être fortement dépendant du compilateur, et la méthode utilisant numpy semble être recommandée.

Lire la sortie fortran avec python

Comment utiliser numpy

Afin de lire les données fortran avec numpy, il est recommandé de sortir avec ʻaccess = 'stream'` (ce n'est pas essentiel car vous pouvez ajuster vous-même l'en-tête, etc.).

Définir un tableau avec fortran et sortie

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a

  a = 1.d0
  
  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  write(idf) a
  close(idf)
  
  stop
end program test

Le moyen le plus simple de le charger avec python est d'utiliser np.fromfile.

import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
f = open('test.dat','rb')
a = np.fromfile(f,endian+'d',ix*jx*kx)
a = a.reshape((ix,jx,kx),order='F')
f.close()

Même si vous utilisez np.fromfile, vous pouvez utiliser np.dtype pour une lecture plus polyvalente. Par exemple, procédez comme suit

import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
f = open('test.dat','rb')
dtype = np.dtype([('a',endian+str(ix*jx*kx)+'d')])
a = np.fromfile(f,dtype=dtype)['a']
a = a.reshape((ix,jx,kx),order='F')
f.close()

Il est plus pratique d'utiliser np.dtype pour traiter plusieurs tableaux. Tout d'abord, fortran génère plusieurs tableaux dans un fichier, comme illustré ci-dessous.

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a,b

  a = 1.d0
  b = 2.d0
  
  open(newunit=idf, file='test.dat',form='unformatted',access='stream')
  write(idf) a,b
  close(idf)
  
  stop
end program test

Pour charger ceci avec python:

import numpy as np

ix, jx, kx = 3, 4, 5
endian='<'
f = open('test.dat','rb')
dtype = np.dtype([('a',endian+str(ix*jx*kx)+'d'),('b',endian+str(ix*jx*kx)+'d')])
data = np.fromfile(f,dtype=dtype)
a = data['a'].reshape((ix,jx,kx),order='F')
b = data['b'].reshape((ix,jx,kx),order='F')
f.close()

Comment utiliser scipy.io.FortranFile

Il est facile d'utiliser scipy.io.FortranFile pour lire les données fortran sans ʻaccess = 'stream'`.

La sortie de fortran est la suivante

program test
  implicit none

  integer :: i,j,k
  integer :: idf
  integer, parameter :: ix = 3, jx = 4, kx = 5
  real(KIND(0.d0)), dimension(ix,jx,kx) :: a

  a = 1.d0
  
  open(newunit=idf, file='test.dat',form='unformatted')
  write(idf) a
  close(idf)
  
  stop
end program test

Le code python pour lire ceci ressemble à ceci

import numpy as np
from scipy.io import FortranFile

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx))
b = np.ones((ix,jx,kx))*2
f = FortranFile('test.dat','r')
a = f.read_record(endian+'('+str(ix)+','+str(jx)+','+str(kx)+')d')
f.close()

Il peut également être lu en utilisant np.dtype comme suit:

import numpy as np
from scipy.io import FortranFile

ix, jx, kx = 3, 4, 5
endian='<'
a = np.ones((ix,jx,kx))
b = np.ones((ix,jx,kx))*2
f = FortranFile('test.dat','r')
dtype = np.dtype([('a',endian+str(ix*jx*kx)+'d')])
a = f.read_record(dtype=dtype)
a = a['a'].reshape(ix,jx,kx,order='F')
f.close()

Recommended Posts

Résumé relatif aux E / S de python et fortran
Résumé des index et des tranches Python
Résumé de la correspondance entre les opérations de tableau ruby et python
Résumé des différences entre PHP et Python
Installation de Python 3 et Flask [Résumé de la construction de l'environnement]
Résumé relatif au traitement itératif Python
Résumé des arguments Python
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
[Python] Erreur de type: résumé des causes et des solutions pour "Aucun type"
J'ai vérifié les versions de Blender et Python
Récapitulatif du traitement de la date en Python (datetime et dateutil)
résumé lié à l'opération de fichier python
J'ai comparé Java et Python!
E / S asynchrones et E / S non bloquantes
Installation source et installation de Python
[python] Résumé de la récupération des listes et des éléments du dictionnaire
Apprenez la "grammaire anglaise" au lieu des mots anglais liés à Python et AI. .. ..
[Python] Résumé de l'utilisation des fonctions de fractionnement et de jointure
Je veux connaître la nature de Python et pip
Construction d'environnement de python et opencv
L'histoire de Python et l'histoire de NaN
Installer SciPy et matplotlib (Python)
Un bref résumé de la collection Python
H29.2.27 ~ 3.5 Résumé de ce que j'ai fait
Ceci et cela des propriétés python
J'ai joué avec PyQt5 et Python3
Coexistence de Python2 et 3 avec CircleCI (1.0)
Réputation des livres Python et des livres de référence
[OpenCV; Python] Résumé de la fonction findcontours
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de la régression logistique
Je souhaite utiliser à la fois la clé et la valeur de l'itérateur Python
Résumé des différences entre Python et PHP (tableau de comparaison des principaux éléments)
Installation du code Visual Studio et installation de python
[Python] Résumé de l'utilisation des pandas
Résumé Python
J'ai comparé argparse standard python3 et python-fire
Extraction de tweet.js (json.loads et eval) (Python)
Résumé de diverses instructions for en Python
Connectez beaucoup de Python ou et et
Résumé Python
Apprenez les mots anglais liés à Python et AI. .. ..
[Python] Résumé de la conversion entre les chaînes de caractères et les valeurs numériques (code ascii)
Résumé des fonctions numpy que je ne connaissais pas
[Python2.7] Résumé de l'utilisation d'unittest
J'ai installé et utilisé Numba avec Python3.5
J'ai 0 ans d'expérience en programmation et je défie le traitement des données avec python
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
Le modèle de projet Python auquel je pense.
Résumé des modules et des classes dans Python-TensorFlow2-
Résumé des méthodes intégrées, etc. de la liste Python
Résumé des techniques utiles de Scrapy en Python
Résumé de l'utilisation de la liste Python
Introduction facile de la série python3 et d'OpenCV3
[Python] Diverses combinaisons de chaînes de caractères et de valeurs
[Python2.7] Résumé de l'utilisation du sous-processus
Résumé de la spécification des options d'axe de Python "numpy.sum (...)"
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
Automatisation égale de l'installation de Python et PyPI