以python sorted()函数方式对pandas.DataFrame进行排序

时间:2018-02-23 10:57:20

标签: python pandas sorting dataframe

描述

长话短说,我需要一种方法来按特定列对DataFrame进行排序,给定一个特定的函数,该函数与python内置sorted()函数中的“key”参数的使用类似。然而pd.DataFrame.sort_value()函数中没有这样的“关键”参数。

现在使用的方法

我必须创建一个新列来存储特定行的“分数”,并在最后删除它。这种方法的问题在于必须生成DataFrame中不存在的列名,并且在按多列排序时可能会更麻烦。

我想知道是否有更合适的方法用于此目的,其中不需要提出新的列名,就像使用sorted()函数并在其中指定参数“key”一样。

更新:我通过使用新对象更改了我的实现,而不是生成除列中的字符串之外的新字符串以避免冲突,如下面的代码所示。

代码

这是示例代码。在此示例中,需要根据行“片段”中的数据长度对DataFrame进行排序。 请勿对特定列的每一行中的对象类型进行其他假设。唯一给出的是列本身和一个函数对象/ lambda表达式(在本例中为:len),它将列中的每个对象作为输入并生成一个值,用于比较。

def sort_table_by_key(self, ascending=True, key=len):
    """
    Sort the table inplace.
    """
    # column_tmp = "".join(self._table.columns)
    column_tmp = object() # Create a new object to avoid column name collision.
    # Calculate the scores of the objects. 
    self._table[column_tmp] = self._table["snippet"].apply(key)
    self._table.sort_values(by=column_tmp, ascending=ascending, inplace=True)
    del self._table[column_tmp]

1 个答案:

答案 0 :(得分:1)

现在没有实现,请检查github issue 3942

我认为您需要argsort,然后按iloc选择:

df = pd.DataFrame({
    'A': ['assdsd','sda','affd','asddsd','ffb','sdb','db','cf','d'],
    'B': list(range(9))
})
print (df)
        A  B
0  assdsd  0
1     sda  1
2    affd  2
3  asddsd  3
4     ffb  4
5     sdb  5
6      db  6
7      cf  7
8       d  8
def sort_table_by_length(column, ascending=True):
    if ascending:
        return df.iloc[df[column].str.len().argsort()]
    else:
        return df.iloc[df[column].str.len().argsort()[::-1]]

print (sort_table_by_length('A'))
        A  B
8       d  8
6      db  6
7      cf  7
1     sda  1
4     ffb  4
5     sdb  5
2    affd  2
0  assdsd  0
3  asddsd  3

print (sort_table_by_length('A', False))
        A  B
3  asddsd  3
0  assdsd  0
2    affd  2
5     sdb  5
4     ffb  4
1     sda  1
7      cf  7
6      db  6
8       d  8

工作原理

首先获得新Series的长度:

print (df['A'].str.len())
0    6
1    3
2    4
3    6
4    3
5    3
6    2
7    2
8    1
Name: A, dtype: int64

然后按argmax按排序值获取索引,使用降序排序this solution

print (df['A'].str.len().argsort())
0    8
1    6
2    7
3    1
4    4
5    5
6    2
7    0
8    3
Name: A, dtype: int64

iloc的最后更改排序:

print (df.iloc[df['A'].str.len().argsort()])
        A  B
8       d  8
6      db  6
7      cf  7
1     sda  1
4     ffb  4
5     sdb  5
2    affd  2
0  assdsd  0
3  asddsd  3