python - font - Applicazione della funzione sulla riga/colonna matrix di numpy




python set axis label (3)

Sto usando Numpy per memorizzare i dati in matrici. Venendo da sfondo R, c'è stato un modo estremamente semplice per applicare una funzione su righe / colonne o entrambe le matrici.

C'è qualcosa di simile per la combinazione python / numpy? Non è un problema scrivere la mia piccola implementazione, ma mi sembra che la maggior parte delle versioni che creerò saranno significativamente meno efficienti / più dispendiose in termini di memoria rispetto a qualsiasi implementazione esistente.

Vorrei evitare di copiare dalla matrice numpy a una variabile locale, ecc., È possibile?

Le funzioni che sto cercando di implementare sono principalmente semplici confronti (es. Quanti elementi di una certa colonna sono più piccoli del numero x o quanti di essi hanno un valore assoluto maggiore di y).

https://code.i-harness.com


La selezione di elementi da un array NumPy basato su una o più condizioni è semplice usando la sintassi densamente bella di NumPy:

>>> import numpy as NP
>>> # generate a matrix to demo the code
>>> A = NP.random.randint(0, 10, 40).reshape(8, 5)
>>> A
  array([[6, 7, 6, 4, 8],
         [7, 3, 7, 9, 9],
         [4, 2, 5, 9, 8],
         [3, 8, 2, 6, 3],
         [2, 1, 8, 0, 0],
         [8, 3, 9, 4, 8],
         [3, 3, 9, 8, 4],
         [5, 4, 8, 3, 0]])


quanti elementi nella colonna 2 sono maggiori di 6?

>>> ndx = A[:,1] > 6
>>> ndx
      array([False,  True, False, False,  True,  True,  True,  True], dtype=bool)
>>> NP.sum(ndx)
      5


quanti elementi nell'ultima colonna di A hanno un valore assoluto maggiore di 3?

>>> A = NP.random.randint(-4, 4, 40).reshape(8, 5)
>>> A
  array([[-4, -1,  2,  0,  3],
         [-4, -1, -1, -1,  1],
         [-1, -2,  2, -2,  3],
         [ 1, -4, -1,  0,  0],
         [-4,  3, -3,  3, -1],
         [ 3,  0, -4, -1, -3],
         [ 3, -4,  0, -3, -2],
         [ 3, -4, -4, -4,  1]])

>>> ndx = NP.abs(A[:,-1]) > 3
>>> NP.sum(ndx)
      0


quanti elementi nelle prime due righe di A sono maggiori o uguali a 2?

>>> ndx = A[:2,:] >= 2
>>> NP.sum(ndx.ravel())    # 'ravel' just flattens ndx, which is originally 2D (2x5)
      2

La sintassi dell'indicizzazione di NumPy è molto simile a quella di R; data la tua scioltezza in R, ecco le differenze chiave tra R e NumPy in questo contesto:

Gli indici NumPy sono basati su zero , in R, l'indicizzazione inizia con 1

NumPy (come Python) ti permette di indicizzare da destra a sinistra usando indici negativi - es.

# to get the last column in A
A[:, -1], 

# to get the penultimate column in A
A[:, -2] 

# this is a big deal, because in R, the equivalent expresson is:
A[, dim(A)[0]-2]

NumPy utilizza la notazione ":" dei due punti per indicare "unsliced" , ad esempio, in R, per ottenere le prime tre righe in A, si utilizzerà, A [1: 3,]. In NumPy, useresti A [0: 2,:] (in NumPy, lo "0" non è necessario, infatti è preferibile usare A [: 2,:]


Quasi tutte le funzioni di Numpy operano su interi array e / o si può dire di operare su un particolare asse (riga o colonna).

Finché puoi definire la tua funzione in termini di funzioni di numpy che agiscono su array numpy o sezioni di array, la tua funzione funzionerà automaticamente su interi array, righe o colonne.

Potrebbe essere più utile chiedere come implementare una particolare funzione per ottenere consigli più concreti.

Numpy fornisce np.vectorize e np.frompyfunc per trasformare le funzioni Python che operano sui numeri in funzioni che operano su array numpy.

Per esempio,

def myfunc(a,b):
    if (a>b): return a
    else: return b
vecfunc = np.vectorize(myfunc)
result=vecfunc([[1,2,3],[5,6,9]],[7,4,5])
print(result)
# [[7 4 5]
#  [7 6 9]]

(Gli elementi del primo array vengono sostituiti dall'elemento corrispondente del secondo array quando il secondo è più grande).

Ma non eccitarti troppo; np.vectorize e np.frompyfunc sono solo zucchero sintattico . In realtà non rendono il tuo codice più veloce. Se la funzione Python sottostante funziona su un valore alla volta, np.vectorize lo alimenterà un elemento alla volta e l'intera operazione sarà piuttosto lenta (rispetto all'uso di una funzione numpy che chiama un C sottostante Implementazione Fortran).

Per contare quanti elementi della colonna x sono più piccoli di un numero y , potresti usare un'espressione come:

(array['x']<y).sum()

Per esempio:

import numpy as np
array=np.arange(6).view([('x',np.int),('y',np.int)])
print(array)
# [(0, 1) (2, 3) (4, 5)]

print(array['x'])
# [0 2 4]

print(array['x']<3)
# [ True  True False]

print((array['x']<3).sum())
# 2





map-function