如何使用键对pandas DataFrame进行排序?

10

我正在寻找一种对 Pandas DataFrame 进行排序的方法。 pd.DataFrame.sort_values 不接受键函数。我可以将其转换为列表,并应用一个键到 sorted 函数,但那会很慢。另一种方式似乎与分类索引有关。我没有固定的行数,因此我不知道分类索引是否适用。

下面是一个示例数据:

输入 DataFrame:

     clouds  fluff
0    {[}      1
1    >>>      2
2     {1      3
3    123      4
4  AAsda      5
5    aad      6

输出数据框:
     clouds  fluff
0    >>>      2
1    {[}      1
2     {1      3
3    123      4
4    aad      6
5  AAsda      5
排序规则(优先级):
  • 首先是特殊字符(按ascii顺序排序)

  • 其次是数字

  • 接下来是小写字母(按字典顺序)

  • 最后是大写字母(按字典顺序)

在纯Python中,我会这样做:

from functools import cmp_to_key

def ks(a, b):
    # "Not exactly this but similar"
    if a.isupper():
        return -1
    else:
        return 1

案例

sorted(['aa', 'AA', 'dd', 'DD'], key=cmp_to_key(ks))

抱歉,您需要提供要翻译的具体文本。
['DD', 'AA', 'aa', 'dd']

你会如何使用Pandas进行操作?

你有检查过这个吗?https://dev59.com/QFkT5IYBdhLWcg3wZuoA - hellpanderr
@hellpanderr,是的,但我不知道如何将这个问题翻译成那种方式。 - Vasantha Ganesh
@Goyo,将示例从Column更改为pd.DataFrame - Vasantha Ganesh
1
这个问题已经在 GitHub 上提交了 issue - Vasantha Ganesh
4个回答

7

从pandas 1.1.0版本开始,pandas.DataFrame.sort_values接受一个类型为callable的参数key

因此,在这种情况下,我们将使用:

df.sort_values(by='clouds', key=kf)

其中kf是在Series类型上操作的键函数。接受并返回Series。


5

从pandas 1.2.0版本开始,我执行了以下操作

import numpy as np
import pandas as pd

df = pd.DataFrame(['aa', 'dd', 'DD', 'AA'], columns=["data"])

# This is the sorting rule
rule = {
    "DD": 1,
    "AA": 10,
    "aa": 20,
    "dd": 30,
    }


def particular_sort(series):
    """
    Must return one Series
    """
    return series.apply(lambda x: rule.get(x, 1000))


new_df = df.sort_values(by=["data"], key=particular_sort)
print(new_df)  # DD, AA, aa, dd

当然,你也可以这样做,但这可能会比较难理解,微笑

new_df = df.sort_values(by=["data"], key=lambda x: x.apply(lambda y: rule.get(y, 1000)))
print(new_df)  # DD, AA, aa, dd

2

这可能很有用,但特殊字符还不确定!它们能真正被排序吗!

import pandas as pd

a = [2, 'B', 'c', 1, 'a', 'b',3, 'C', 'A']

df = pd.DataFrame({"a": a})
df['upper'] = df['a'].str.isupper()
df['lower'] = df['a'].str.islower()
df['int'] = df['a'].apply(isinstance,args = [int])

df2 = pd.concat([df[df['int'] == True].sort_values(by=['a']), 
           df[df['lower'] == True].sort_values(by=['a']),
           df[df['upper'] == True].sort_values(by=['a'])])

print(df2)

   a    upper   lower   int
3   1   NaN     NaN     True
0   2   NaN     NaN     True
6   3   NaN     NaN     True
4   a   False   True    False
5   b   False   True    False
2   c   False   True    False
8   A   True    False   False
1   B   True    False   False
7   C   True    False   False

你也可以通过创建新的True False列一步完成!

a = [2, 'B', 'c', 1, 'a', 'b',3, 'C', 'A']
df = pd.DataFrame({"a": a})
df2 = pd.concat([df[df['a'].apply(isinstance,args = [int])].sort_values(by=['a']), 
           df[df['a'].str.islower() == True].sort_values(by=['a']),
           df[df['a'].str.isupper() == True].sort_values(by=['a'])])

    a
3   1
0   2
6   3
4   a
5   b
2   c
8   A
1   B
7   C

2

这似乎可以工作:

def sort_dataframe_by_key(dataframe: DataFrame, column: str, key: Callable) -> DataFrame:
    """ Sort a dataframe from a column using the key """
    sort_ixs = sorted(np.arange(len(dataframe)), key=lambda i: key(dataframe.iloc[i][column]))
    return DataFrame(columns=list(dataframe), data=dataframe.iloc[sort_ixs].values)

它通过了测试:

def test_sort_dataframe_by_key():
    dataframe = DataFrame([{'a': 1, 'b': 2, 'c': 3}, {'a': 2, 'b': 1, 'c': 1}, {'a': 3, 'b': 4, 'c': 0}])
    assert sort_dataframe_by_key(dataframe, column='a', key=lambda x: x).equals(
           DataFrame([{'a': 1, 'b': 2, 'c': 3}, {'a': 2, 'b': 1, 'c': 1}, {'a': 3, 'b': 4, 'c': 0}]))
    assert sort_dataframe_by_key(dataframe, column='a', key=lambda x: -x).equals(
           DataFrame([{'a': 3, 'b': 4, 'c': 0}, {'a': 2, 'b': 1, 'c': 1}, {'a': 1, 'b': 2, 'c': 3}]))
    assert sort_dataframe_by_key(dataframe, column='b', key=lambda x: -x).equals(
           DataFrame([{'a': 3, 'b': 4, 'c': 0}, {'a': 1, 'b': 2, 'c': 3}, {'a': 2, 'b': 1, 'c': 1}]))
    assert sort_dataframe_by_key(dataframe, column='c', key=lambda x: x).equals(
           DataFrame([{'a': 3, 'b': 4, 'c': 0}, {'a': 2, 'b': 1, 'c': 1}, {'a': 1, 'b': 2, 'c': 3}]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接