熊猫自然分拣

时间:2018-12-20 14:32:34

标签: python pandas sorting dataframe natsort

我在熊猫里有这些数据

data = [
        ['ID', 'Time', 'oneMissing', 'singleValue', 'empty', 'oneEmpty'],
        ['CS1-1', 1,  10000, None, None, 0],
        ['CS1-2', 2, 20000, 0.0,  None, 0],
        ['CS1-1', 2, 30000, None, None, 0],
        ['CS1-2', 1,  10000, None, None, None],
        ['CS1-11', 1, None,  0.0,  None, None],
        ['CS1-2', 3, 30000, None, None, None]
    ]

我尝试按ID和“时间”列进行排序,因此结果应类似于

        'CS1-1', 1,  10000, None, None, 0
        'CS1-1', 2, 30000, None, None, 0
        'CS1-2', 1,  10000, None, None, None
        'CS1-2', 2, 20000, 0.0,  None, 0
        'CS1-2', 3, 30000, None, None, None
        'CS1-11', 1, None,  0.0,  None, None
    ]

我正在使用pandas数据框进行排序,也尝试过与natsort一起使用,但无法正常工作。要么我得到索引包含重复项的错误(我使用ID作为索引),要么它按字符串值排序。

此处的ID仅是示例。我不知道它将是哪种格式,可能是数字字母或数字字母NUMBER。我只需要比较所有数字作为一个数字。我看过“ natsort”,似乎对数组确实正确。因此,我认为应该可以使用它对ID进行排序,然后对数据重新编制索引。

我看过类似这样的多个消息来源,但没有任何运气: Alphanumeric sorting Sort dataframes

4 个答案:

答案 0 :(得分:3)

使用local2.* @<ip_addr> <ip_addr>,然后使用索引重新索引str.extract

sort_values

这是基于您的ID列采用“ XXX-NUMBER”格式的假设。


一个万无一失的解决方案将涉及使用natsort模块,该模块擅长快速自然排序。只需稍加注油,我们就可以对您的数据进行分类。

df

使用PyPi安装:idx = (df.assign(ID2=df.ID.str.extract(r'(\d+)$').astype(int)) .sort_values(['ID2', 'Time']) .index) df.iloc[idx] ID Time oneMissing singleValue empty oneEmpty 0 CS1-1 1 10000.0 NaN None 0.0 2 CS1-1 2 30000.0 NaN None 0.0 3 CS1-2 1 10000.0 NaN None NaN 1 CS1-2 2 20000.0 0.0 None 0.0 5 CS1-2 3 30000.0 NaN None NaN 4 CS1-11 1 NaN 0.0 None NaN

答案 1 :(得分:2)

注意:此方法假定您希望对 ABC-X 形式的 ID 使用 X 进行数字排序。 / strong>

<代码> np.lexsort < / code> 支持按多个序列排序,并避免了向数据框添加额外的序列。本示例按数字编号 ID 的后缀排序,按 Time 排序 then

  df = pd.DataFrame(数据[1:],列=数据[0])

id_num = df ['ID']。str.split('-')。str [-1] .astype(int)

df = df.iloc [np.lexsort((df ['Time'],id_num))]

打印(df)

       ID时间一个缺少单值空一个空
0 CS1-1 1 10000.0 NaN无0.0
2 CS1-1 2 30000.0 NaN无0.0
3 CS1-2 1 10000.0 NaN无NaN
1 CS1-2 2 20000.0 0.0无0.0
5 CS1-2 3 30000.0 NaN无NaN
4 CS1-11 1 NaN 0.0无NaN
 

答案 2 :(得分:0)

我认为您正在寻找sort_values

df.sort_values(['ID','Time'])

注意:如果您希望CS1-11CS1-2之后(这不是标准的字符串顺序),则可能需要引入一个长度列,例如

df['len_ID'] = df['ID'].str.len()
df.sort_values(['len_ID', 'ID','Time'])

答案 3 :(得分:0)

可以使用sorted对ID字符串的子集进行排序来获得所需的输出-请参见this answer

pd.DataFrame(
    sorted(df.values, key=lambda x: int(x[0].split('-')[1])),
    columns=df.columns
)

在这里,lambda函数将ID中的“-”后的字符转换为整数,然后对它们进行排序。这实现了“自然”排序。

       ID  Time  oneMissing  singleValue empty  oneEmpty
0   CS1-1     1     10000.0          NaN  None       0.0
1   CS1-1     2     30000.0          NaN  None       0.0
2   CS1-2     2     20000.0          0.0  None       0.0
3   CS1-2     1     10000.0          NaN  None       NaN
4   CS1-2     3     30000.0          NaN  None       NaN
5  CS1-11     1         NaN          0.0  None       NaN