2015-11-21 15 views
6

Supponiamo che ho una lista:Come indice più elementi di array con intervalli in Python

import numpy as np 
a = [2, 4, 6, 8, ..., 1000] # total 500 elements 
b = np.array(a)    # numpy version 

voglio arrivare 1o-100i, 201i a 300 °, 401 ° a 500 ° elementi e trasformarli in una nuova matrice.

A tal fine, ho provato i seguenti codici:

a_sub = a[0:100] + a[200:300] + a[400:500] 
b_sub = np.concatenate((b[0:100], b[200:300], b[400:500])) 

ma voglio farlo con un semplice oneline-indicizzazione

Di ':

a_sub = a[(0:100, 200:300, 400:500)] 
a_sub = a[[0:100, 200:300, 400:500]] 
b_sub = b[[0:100, 200:300, 400:500]] 
b_sub = b[[0:100, 200:300, 400:500]] 

Ma la sopra sono tutti invalidi e non ho potuto trovare tale indicizzazione oneliner.

+1

Non so se questo è possibile. O vuoi questo 'a_sub = b [intervallo (0,100) + intervallo (200,300) + intervallo (400,500)]' –

+0

Voglio dire che non puoi indicizzare una lista come quella in una riga specificatamente 'a_sub = a [(0: 100, 200: 300, 400: 500)] ' –

+0

Qualcuna delle soluzioni pubblicate qui funziona per te? – Divakar

risposta

1

È possibile convertire le sezioni in un array maschera (affettando un array-ones) e unire le matrici maschera utilizzando l'operatore | (o).

ones = np.ones(b.shape, dtype = bool) 
mask = ones[ 0:100] | ones[200:300] | ones[400:500] 
b_sub = b[mask] 

Nota che se i tuoi fette sovrappongono, o appaiono in un non aumento di ordine, questo si traduce con un allineamento diverso dal tuo codice originale (voci non si ripeteranno, e apparirà sempre nello stesso ordine come nel matrice originale).

3

Si potrebbe usare rimodellare con np.reshape e slicing, in questo modo -

np.array(a).reshape(-1,100)[::2].ravel() 

Se a è un array NumPy, si potrebbe fare in questo modo -

a.reshape(-1,100)[::2].ravel() 
1

bene, è puro python, ma forse potrebbe risolvere la tua domanda

a = [2, 4, 6, 8, ..., 1000] 
slices = ((0, 100), (200, 300), (400, 500)) 

def new_from_slices(list_, slices): 
    return list(itertools.chain(*[list_[s[0]:s[1]] for s in slices])) 
new_from_slices(a, slices) 
0

due altri uno- Fodera:

[x for i,x in enumerate(a) if i//100%2==0] #python 
b[np.arange(len(b))//100%2==0] # numpy 
1

Si potrebbe anche usare np.split:

a = range(2, 1002, 2) 
edges = [100, 200, 300, 400] 
subarrays = np.split(a, edges) 
b = np.hstack(subarrays[i] for i in [0, 2, 4]) 
0

o utilizzando hstack (+ aggiunge l'elemento valori saggio)

a = np.arange(1000) 
limits = [(0, 100), (200, 300), (400, 500)] 
b = np.hstack(a[low:high] for low, high in limits) 
Problemi correlati