按Pandas中的列子值排序

时间:2017-08-02 19:27:44

标签: python pandas sorting

我的pandas DataFrame看起来像这样:

day

其中--------------------------------------- Name | Stats --------------------------------------- Bob | { age : 42, profession: IT } Jill | { age : 35, profession: Engineer } Patric | { age : 37, profession: Student } --------------------------------------- 是一个类,而Statsage都是该类的属性。

我希望通过profession上的某个属性对该表进行排序。例如,按人的年龄对其进行排序,以使表格如下:

Stats

Pandas有没有办法做到这一点?我只找到了按整列排序的方法

由于

2 个答案:

答案 0 :(得分:2)

使用数据框的一个主要方面是键入列以实现高效存储和计算速度(例如int64,float64,object等)。您的数据结构不合理;您应该为Stats中的每个字段设置单独的列。有关详细信息,请参阅Tidy Data

df2 = df[['Name']].assign(age=[d.get('age') for d in df['Stats']],
                          profession=[d.get('profession') for d in df['Stats']])

然后很容易处理您的数据。

>>> df2.sort_values('age')
     Name  age profession
1    Jill   35   Engineer
2  Patric   37    Student
0     Bob   42         IT

答案 1 :(得分:2)

<强>解决方案
您可以使用argsort查找相应的顺序并将其传递给iloc。但是,您需要创建数据框才能在argsort列上运行age

df.iloc[pd.DataFrame(df.Stats.values.tolist()).age.argsort()]

     Name                                  Stats
1    Jill  {'age': 35, 'profession': 'Engineer'}
2  Patric   {'age': 37, 'profession': 'Student'}
0     Bob        {'age': 42, 'profession': 'IT'}

在阅读@Alexander's answer...后,我想出了一些结合他的想法和我的想法的东西。如果有人发现这部分有用,请不要忘记提出他的答案。

df.iloc[np.argsort([x.get('age') for x in df.Stats])]

<强>时序
小样本数据

%timeit df.iloc[pd.DataFrame(df.Stats.values.tolist()).age.argsort()]
%timeit df.iloc[np.argsort([x.get('age') for x in df.Stats])]
%timeit df.iloc[np.argsort([x.get('age') for x in df.Stats.values.tolist()])]

1000 loops, best of 3: 756 µs per loop
1000 loops, best of 3: 225 µs per loop
1000 loops, best of 3: 207 µs per loop

设置

df = pd.DataFrame(dict(
    Name='Bob Jill Patric'.split(),
    Stats=[
        dict(age=42, profession='IT'),
        dict(age=35, profession='Engineer'),
        dict(age=37, profession='Student')
    ]
))