2015-02-09 13 views

risposta

12

ci sono una manciata di funzioni in pd.algos che potrebbe essere utile. Sono tutti i dettagli di implementazione senza documenti, in modo che possa cambiare da una release all'altra:

>>> pd.algos.is[TAB] 
pd.algos.is_lexsorted   pd.algos.is_monotonic_float64 pd.algos.is_monotonic_object 
pd.algos.is_monotonic_bool  pd.algos.is_monotonic_int32 
pd.algos.is_monotonic_float32 pd.algos.is_monotonic_int64  

Le is_monotonic_* funzioni accettano un array del DTYPE specificato e un valore booleano "tipo tempo" che dovrebbe essere False per la maggior parte dei casi d'uso. (Panda lo imposta su True per un caso che coinvolge tempi rappresentati come numeri interi.) Il valore di ritorno è una tupla il cui primo elemento rappresenta se l'array è monotonicamente non decrescente e il cui secondo elemento rappresenta se l'array è monotonicamente non crescente. Altri elementi tupla sono dipendenti dalla versione:

>>> df = pd.DataFrame({"A": [1,2,2], "B": [2,3,1]}) 
>>> pd.algos.is_monotonic_int64(df.A.values, False)[0] 
True 
>>> pd.algos.is_monotonic_int64(df.B.values, False)[0] 
False 

Tutte queste funzioni assumono un dtype ingresso specifico, anche is_lexsorted, che assume l'input è una lista di int64 array. Passare così il DTYPE sbagliato, e diventa molto confuso:

In [32]: pandas.algos.is_lexsorted([np.array([-2, -1], dtype=np.int64)]) 
Out[32]: True 
In [33]: pandas.algos.is_lexsorted([np.array([-2, -1], dtype=float)]) 
Out[33]: False 
In [34]: pandas.algos.is_lexsorted([np.array([-1, -2, 0], dtype=float)]) 
Out[34]: True 

Non sono del tutto sicuro perché Series non hanno già una sorta di corto circuito is_sorted. Potrebbe esserci qualcosa che lo rende più complicato di quanto sembri.

+0

Incredibile sia per avermi indirizzato a questa libreria pd.algos, sia per la punta! Qualche possibilità che tu conosca un modo semplice per affrontare tipi decrescenti? Lo voglio ordinato in modo da poter tirare la prima (più grande) fila. Posso semplicemente chiamare len() e ottenere l'ultima riga, se necessario, cercando solo la velocità. –

+1

@nick_eu: non proprio, temo. Puoi sempre usare '.iloc [-1]' per ottenere l'ultima riga, però. – DSM

+0

ovviamente! non ci avevo pensato. Grazie! –

7

È possibile utilizzare il metodo NumPy:

import numpy as np 

def is_df_sorted(df, colname): 
    return (np.diff(df[colname]) > 0).all() 

un approccio più diretto (come da te suggerito, ma tu dici che non lo vuoi ..) è di convertire ad un indice e utilizzare la proprietà is_monotonic :

import pandas as pd 

def is_df_sorted(df, colname): 
    return pd.Index(df[colname]).is_monotonic 
+0

Grazie shx2! Questo è il mio obiettivo, ma risulta: assert(df.column.diff()[1:] <= 0).all() (il primo valore di diff è un NaN) è più lento di un semplice ordinamento con un mergesort. Inoltre, is_monotonic() non tollera colonne debolmente monotone, quindi non funziona nel mio caso. :/Ma forse su un set di dati più grande sarebbe il profitto. –

+2

Forse usare '> = 0'? – DSM

+0

sto ordinando in modo discendente così posso prendere il primo oggetto ... –

Problemi correlati