长话短说,我需要一种方法来按特定列对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]
答案 0 :(得分:1)
现在没有实现,请检查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
工作原理:
首先获得新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