描述
长话短说,我需要一种方法来按特定列对 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]
最佳答案
现在还没有实现,检查github issue 3942 .
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
工作原理:
首先获取新系列
的长度:
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
关于python - 以 python sorted() 函数方式对 pandas.DataFrame 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48946238/