2016-09-13 2 views
0

J'essaie d'utiliser des boucles for numpy plutôt que imbriquées et d'essayer de trouver si une valeur est dans une tolérance particulière.Énoncés multiples d'évaluation de Numpy in1D

Le code en python utilisant les boucles imbriquées fonctionne très bien et j'obtiens les résultats que je recherche mais n'est malheureusement pas évolutif et prend quelques heures quand la taille de la liste est 200k plus les éléments.

Ce que j'ai maintenant une deuxième itération du processus est:

import numpy as np 
import numpy.ma as ma 
from numpy import newaxis 

#some data provided as an example 
a= np.array([['id1', 8988, 7997, 210.0, 240.0, 180, 300, 7000.0, 9038, 8938, 8047, 7947, 231.0, 189.0, 8400.0, 5600.0], 
['id2', 7314, 5613, 210.0, 240.0, 180, 300, 7000.0, 7364, 7264, 5663, 5563, 231.0, 189.0, 8400.0, 5600.0], 
['id3', 5520, 9888, 35.0, 55.0, -125, 235, 7000.0, 5570, 5470, 9938, 9838, 38.5, 31.5, 8400.0, 5600.0], 
['id4', 6270, 4270, 0.0, 90.0, -90, 270, 7000.0, 6320, 6220, 4320, 4220, 0.0, 0.0, 8400.0, 5600.0]]) 

print(a) 

validation = np.ma.MaskedArray(((a[:, 1:2] <= a[:, 8:9]) & (a[:, 1:2] >= a[:, 9:10])) \ 
    & ((a[:, 2:3] <= a[:, 10:11]) & (a[:, 2:3] >= a[:, 11:12])) \ 
    & ((a[:, 3:4] <= a[:, 12:13]) & (a[:, 3:4] >= a[:, 13:14])) \ 
    & ((a[:, 7:8] <= a[:, 14:15]) & (a[:, 7:8] >= a[:, 15:]))) 

e = np.in1d(a[:, 1:2], a[validation]) <-- this is were I try to apply the check for tolerances 
e1 = np.where(e[:, newaxis], a[:, :1], np.zeros(1, dtype=int)) 
ef = e1[~np.all(e1 == 0, axis=0)] 

print('Final array', ef) 

Sur la première tentative à l'aide de meshgrid de numpy pour créer toutes les combinaisons, un pour chaque comparaison, et puis en faisant un numpy.where sur la résultats cela fonctionne mais en utilisant 100k plus des articles, la quantité totale de RAM requise est plus de 150 Go de RAM.

Toute aide, conseil, commentaire est apprécié.

+0

Pourquoi utiliser' array' masqué? Commencez avec cette expression logique. Cela devrait être un tableau de forme '(n, 1)' et dtype booléen. Une autre chose, passez la tentative de travailler avec un tableau 2d.Mots 'np.in1d' dans' 1d'. – hpaulj

Répondre

0

Si je copie-n-coller votre a je reçois un tableau de 4x16 de chaînes

In [37]: a 
Out[37]: 
array([['id1', '8988', '7997', '210.0', '240.0', '180', '300', '7000.0', 
     '9038', '8938', '8047', '7947', '231.0', '189.0', '8400.0', 
     '5600.0'], 
     .... 
     dtype='<U6') 

votre expression validation Appliquer à ce produit (oublier le bit Maskedarray). Bien sûr, il essaie de faire une comparaison des chaînes.

array([[ True], 
     [ True], 
     [ True], 
     [ True]], dtype=bool) 

Si je supprime la colonne id je reçois un 4x15 de flotteurs

In [39]: a 
Out[39]: 
array([[ 8988. , 7997. , 210. , 240. , 180. , 300. , 7000. , 
     9038. , 8938. , 8047. , 7947. , 231. , 189. , 8400. , 
     5600. ], 
...]]) 

ce, je pense que le test validation peut être simplifié à:

In [41]: ((a[:, 0] <= a[:, 7]) & (a[:, 0] >= a[:, 8])) \ 
    ...:  & ((a[:, 1] <= a[:, 9]) & (a[:, 1] >= a[:, 10])) \ 
    ...:  & ((a[:, 2] <= a[:, 11]) & (a[:, 2] >= a[:, 12])) \ 
    ...:  & ((a[:, 6] <= a[:, 13]) & (a[:, 6] >= a[:, 14])) 
Out[41]: array([ True, True, True, True], dtype=bool) 

Quelle est cette font?

e = np.in1d(a[:, 1:2], a[validation]) 

a[validation] est d'autant ok rangées de a; a[:,0] est la première valeur de chaque ligne. Mais np.in1d est destiné à vérifier le contenu d'un tableau 1d par rapport au contenu d'un autre 1d. Comme vous l'avez écrit, il utilise 2 tableaux 2d.

À ce stade, je vais abandonner.

Construisez un scénario de test plus simple et assurez-vous qu'il fonctionne à chaque étape. Afficher les valeurs intermédiaires Ensuite, nous pouvons discuter de la ou des étapes où cela ne fonctionne pas.

0

Comme hpaulj dit, d'abord se débarrasser des id. Deuxièmement, pourquoi vos tolérances et vos valeurs sont-elles dans le même tableau? Si vous aviez min_tol et max_tol dans des tableaux séparés, vous pourriez le faire beaucoup plus facilement.

Vous avez probablement besoin de quelque chose comme (après avoir enlevé les id « s):

min_tol = a[:, 8:15:2] 
max_tol = a[:, 7:14:2] 
a_val = np.c_[a[:, :3], a[:, 6]] 
validation = (a_val >= min_tol) & (a_val <= max_tol) 

Bien que je ne suis vraiment pas sûr à ce stade ...