python-3.x - 首先按时间戳值对 pandas 中的行进行排序,然后按特定顺序对列的分类值进行排序
问题描述
我有一个熊猫数据框,其中有一列“用户”,其中包含分类值(a、b、c、d)。我只关心两个类别的升序排列(a,d)。所以 (a,b,c,d) 和 (a,c,b,d) 都适合我。
如何创建排序是问题的第一部分?
其次,我有另一列包含“时间戳”。我想首先按“时间戳”对我的行进行排序,然后对于具有相同时间戳的行,我想使用上述分类值的排序进行排序。
假设我的数据框看起来像这样。
+-----------+------+
| Timestamp | User |
+-----------+------+
| 1 | b |
| 2 | d |
| 1 | a |
| 1 | c |
| 1 | d |
| 2 | a |
| 2 | b |
+-----------+------+
我希望首先发生这种排序
+-----------+------+
| Timestamp | User |
+-----------+------+
| 1 | b |
| 1 | a |
| 1 | c |
| 1 | d |
| 2 | d |
| 2 | a |
| 2 | b |
+-----------+------+
其次是“用户”的分类排序
+-----------+------+
| Timestamp | User |
+-----------+------+
| 1 | a |
| 1 | b |
| 1 | c |
| 1 | d |
| 2 | a |
| 2 | b |
| 2 | d |
+-----------+------+
或者
+-----------+------+
| Timestamp | User |
+-----------+------+
| 1 | a |
| 1 | c |
| 1 | b |
| 1 | d |
| 2 | a |
| 2 | b |
| 2 | d |
+-----------+------+
如您所见,“c”和“b”的顺序无关紧要。
解决方案
您可以在有序分类中指定顺序,categories
然后调用DataFrame.sort_values
:
df['User'] = pd.Categorical(df['User'], ordered=True, categories=['a','b','c','d'])
df = df.sort_values(['Timestamp','User'])
print (df)
Timestamp User
2 1 a
0 1 b
3 1 c
4 1 d
5 2 a
6 2 b
1 2 d
如果有很多值User
可以动态创建类别:
vals = ['a', 'd']
cats = vals + np.setdiff1d(df['User'], vals).tolist()
print (cats)
['a', 'd', 'b', 'c']
df['User'] = pd.Categorical(df['User'], ordered=True, categories=cats)
df = df.sort_values(['Timestamp','User'])
print (df)
Timestamp User
2 1 a
4 1 d
0 1 b
3 1 c
5 2 a
1 2 d
6 2 b