I can check if the index of a pandas.DataFrame() is monotonically increasing by using is_monotonic method. However, I would like to check if one of the column value is strictly increasing in value(float/integer) ?
In [13]: my_df = pd.DataFrame([1,2,3,5,7,6,9])
In [14]: my_df
Out[14]:
0
0 1
1 2
2 3
3 5
4 7
5 6
6 9
In [15]: my_df.index.is_monotonic
Out[15]: True
Pandas 0.19 added a public Series.is_monotonic
API (previously, this was available only in the undocumented algos
module).
(Updated) Note that despite its name, Series.is_monotonic
only indicates whether a series is monotonically increasing (equivalent to using Series.is_monotonic_increasing
). For the other way around, use Series.is_monotonic_decreasing
.
Anyway, both are non-strict, but you can combine them with is_unqiue
to get strictness.
e.g.:
my_df = pd.DataFrame([1,2,2,3], columns = ['A'])
my_df['A'].is_monotonic # non-strict
Out[1]: True
my_df['A'].is_monotonic_increasing # equivalent to is_monotonic
Out[2]: True
(my_df['A'].is_monotonic_increasing and my_df['A'].is_unique) # strict
Out[3]: False
my_df['A'].is_monotonic_decreasing # Other direction (also non-strict)
Out[4]: False
You can use apply
to run this at a DataFrame level:
my_df = pd.DataFrame({'A':[1,2,3],'B':[1,1,1],'C':[3,2,1]})
my_df
Out[32]:
A B C
0 1 1 3
1 2 1 2
2 3 1 1
my_df.apply(lambda x: x.is_monotonic)
Out[33]:
A True
B True
C False
dtype: bool
Probably the best way is to obtain a dataframe column as a numpy array without copying data around (using the .values
property after column selection via indexing), and to then use a numpy-based test for checking monotonicity:
def monotonic(x):
return np.all(np.diff(x) > 0)
monotonic(df[0].values)
A pure Python implementation, borrowed from here: Python - How to check list monotonicity
def strictly_increasing(L):
return all(x<y for x, y in zip(L, L[1:]))
If two indices are equal, they won't be unique. So you can just use:
my_df.Index.is_monotonic and my_df.Index.is_unique
These attributes are documented in version 15.2; is_unique is mentioned sketchily in 14.1 but just worked for me. See
http://pandas.pydata.org/pandas-docs/version/0.15.2/api.html#index
http://pandas.pydata.org/pandas-docs/version/0.14.1/generated/pandas.Index.html
I understand that by strictly increasing you mean that the values are integers and that neighbors are separated by exactly 1? As discussed here, this is a simple method for checking named criterion:
def is_coherent(seq):
return seq == range(seq[0], seq[-1]+1)
Using it with the first column of your my_df
might look like so:
is_coherent(my_df[0].tolist())
you can just math this one:
diff = df[0] - df[0].shift(1)
is_monotonic = (diff < 0).sum() == 0 or (diff > 0).sum() == 0
all you're checking here is that either the differences are all >= 0 or all <= 0.
edit: since you only want strictly increasing, then it's just:
is_monotonic = (diff <= 0).sum() == 0