Comment découper une matrice multidimensionnelle en fonction des valeurs de colonne avec numpy ?

Published: 22 septembre 2023

Tags: Python; Numpy;

DMCA.com Protection Status

Une étude de cas sur la façon de découper une matrice multidimensionnelle en fonction des valeurs de la colonne avec numpy :

Étude de cas

Discutons d'un exemple réaliste où nous avons une matrice multidimensionnelle (appelée ci-après data) de forme :

(3,1500, 2500)

dim 0 = longitude
dim 1 = latitude
dim 2 = a physical value (the fire radiative power FRP for instance)

L'objectif est d'extraire une matrice plus petite pour une plage donnée de latitudes et de longitudes.

Données

Données minimum longitude data[0,:,:].min()

-184.37672

Données longitude maximales data[0,:,:].max()

-89.623276

Données minimum latitude data[1,:,:].min()

14.57134,

Données maximum latitude données[1,:,:].max()

53.500195

Notre objectif est de localiser et obtenir des valeurs situées à proximité (avec +/- 0,25 degré) :

williams_flats_long = -118.49064628838096
williams_flats_lat = 47.9849149578827

Solution

Il est facile de découper une matrice lorsque les index sont connus avec NumPy. Cependant, dans l'exemple précédent, nous n'avions pas cette information, donc notre premier objectif était de trouver les index en fonction de ces exigences :

longitude > williams_flats_long-0.25 & longitude< williams_flats_long+0.25

latitude > williams_flats_lat-0.25 & latitude <williams_flats_lat+0.25)

Dans le passé, je remplissais généralement un dataframe avec mes valeurs en premier lieu, car cette méthode était efficace pour gérer des types de données mixtes :

import pandas as pd

df = pd.DataFrame()

x_axis_size = data.shape[2]
y_axis_size = data.shape[1]

xv, yv = np.meshgrid(np.arange(0,x_axis_size), np.arange(0,y_axis_size))

df['sample'] = xv.flatten() 
df['line'] = yv.flatten()

df['longitude'] = data[0,:,:].ravel()
df['latitude'] = data[1,:,:].ravel()

df['Power'] = data[2,:,:].ravel()

Le code ci-dessus générera le DataFrame suivant:

             sample  line   longitude   latitude  Power
    0             0     0 -184.376724  53.500195    NaN
    1             1     0 -184.310455  53.493004    NaN
    2             2     0 -184.244812  53.486046    NaN
    3             3     0 -184.178406  53.478687    NaN
    4             4     0 -184.112915  53.471695    NaN
    ...         ...   ...         ...        ...    ...
    3749995    2495  1499 -112.517677  14.803576    NaN
    3749996    2496  1499 -112.495865  14.804007    NaN
    3749997    2497  1499 -112.474197  14.804358    NaN
    3749998    2498  1499 -112.452446  14.804746    NaN
    3749999    2499  1499 -112.430595  14.805193    NaN

Ici, nous avons ajouté deux nouvelles colonnes, échantillon et ligne, qui font référence aux indexes des données de la matrice.

Maintenant, nous pouvons appliquer les deux conditions précédentes à notre dataframe et le filtrer en conséquence :

df = df[ (df['longitude'] > williams_flats_long-0.25) & (df['longitude']<williams_flats_long+0.25) ]
df = df[ (df['latitude'] > williams_flats_lat-0.25) & (df['latitude']<williams_flats_lat+0.25) ]

donne

            sample  line   longitude   latitude  Power
    211870    1870    84 -118.726280  48.206997    NaN
    211871    1871    84 -118.694878  48.208351    NaN
    211872    1872    84 -118.663307  48.209919    NaN
    211873    1873    84 -118.631660  48.211582    NaN
    211874    1874    84 -118.600403  48.212662    NaN
    ...        ...   ...         ...        ...    ...
    246887    1887    98 -118.392639  47.753323    NaN
    246888    1888    98 -118.361153  47.755108    NaN
    246889    1889    98 -118.329903  47.756531    NaN
    246890    1890    98 -118.298660  47.757881    NaN
    246891    1891    98 -118.267349  47.759369    NaN

et trouver les index :

idx_min = df['sample'].min()
idx_max = df['sample'].max()

print(idx_min,idx_max)

donne

1870 1891

et

jdx_min = df_sub['line'].min()
jdx_max = df_sub['line'].max()

print(jdx_min,jdx_max)

donne

84 98

La segmentation de la matrice est désormais une procédure simple qui nous permet de sélectionner rapidement la région de notre choix à mettre en évidence :

selected_data = data[:,jdx_min:jdx_max,idx_min:idx_max]

Références

Liens Site
numpy.argwhere umpy.org
numpy.where numpy.org