检查非索引列是否在Pandas中排序

nic*_*_eu 12 python pandas

有没有办法测试数据帧是否按照不是索引的给定列进行排序(即非索引列的等效于is_monotonic())而不重新调用排序,并且不将列转换为指数?

DSM*_*DSM 17

有一些功能pd.algos可能有用.它们都是未记录的实现细节,因此它们可能会在不同版本之间发生变化:

>>> 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    
Run Code Online (Sandbox Code Playgroud)

这些is_monotonic_*函数采用指定dtype的数组和一个应该False适用于大多数用例的"timelike"布尔值.(Pandas将其设置True为涉及以整数表示的时间的情况.)返回值是一个元组,其第一个元素表示数组是否单调非递减,其第二个元素表示数组是否单调非递增.其他元组元素依赖于版本:

>>> 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
Run Code Online (Sandbox Code Playgroud)

所有这些函数都假设一个特定的输入dtype,甚至is_lexsorted是假定输入是一个int64数组列表.传递错误的dtype,它真的很混乱:

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
Run Code Online (Sandbox Code Playgroud)

我不完全确定为什么系列没有某种短路is_sorted.可能有些东西比它看起来更棘手.

  • 看起来现在在`pandas._libs.algos.is_lexsorted`。请注意,它确实需要 `int64` dtype (2认同)

shx*_*hx2 12

你可以使用numpy方法:

import numpy as np

def is_df_sorted(df, colname):
    return (np.diff(df[colname]) > 0).all()
Run Code Online (Sandbox Code Playgroud)

更直接的方法(就像你建议的那样,但你说你不想要它......)是转换为索引并使用is_monotonic属性:

import pandas as pd

def is_df_sorted(df, colname):
    return pd.Index(df[colname]).is_monotonic
Run Code Online (Sandbox Code Playgroud)

  • 也许使用`> = 0`? (2认同)

Kon*_*tin 5

同时,由于0.19.0,有pandas.Series.is_monotonic_increasingpandas.Series.is_monotonic_decreasingpandas.Series.is_monotonic

  • 这应该是公认的答案 (5认同)