目录
- 1. 对一维array中的数值进行从大到小排序
- 2. 将DataFrame的列逆序排列
- 3. 根据字符串中的数字进行排序
- 3.2 啊
- 4. 列表
- 参考资料
1. 对一维array中的数值进行从大到小排序
import numpy as np
a = np.array([5,6,8,2,1,7,5,3,90,78,62,5,4,2,9,4])
# b = a.sort(axis=0,kind='quicksort',order=None)
b = sorted(a,reverse=True)
print('a: ', a)
print('b: ', b)
输出:
a: [ 5 6 8 2 1 7 5 3 90 78 62 5 4 2 9 4]
b: [90, 78, 62, 9, 8, 7, 6, 5, 5, 5, 4, 4, 3, 2, 2, 1]
2. 将DataFrame的列逆序排列
https://blog.csdn.net/ljr_123/article/details/122157636
3. 根据字符串中的数字进行排序
colname = ['time', 'ws_148-A_Avg', 'ws_72-A_Avg', 'ws_150-A_Avg', 'ws_70-A_Avg', 'ws_152-A_Avg', 'ws_68-A_Avg', 'ws_154-A_Avg', 'ws_66-A_Avg', 'ws_105-A_Avg', 'Unnamed: 10']
a = colname[1:-1]
a.sort(key=lambda l: int(re.findall('\d+', l)[0]))
a
Out[15]:
['ws_66-A_Avg', 'ws_68-A_Avg', 'ws_70-A_Avg', 'ws_72-A_Avg', 'ws_105-A_Avg', 'ws_148-A_Avg', 'ws_150-A_Avg', 'ws_152-A_Avg', 'ws_154-A_Avg']
lst = ['123', '385', '674', '147'] # 依据第二位数字进行排序
lst.sort(key=lambda l: l[1]) # 利用key索引列表中每个元素的第二个位置,并依此排序
print(lst)
# result = ['123', '147', '674', '385']
lst = ['pic-1', 'pic-3', 'pic-2', 'pic-10', 'pic-6']
lst.sort() # 当字符串中的数字不止一位时无法简单利用key进行索引
print(lst)
# 你会发现 result = ['pic-1', 'pic-10', 'pic-2', 'pic-3', 'pic-6'] 不合自己要求,这个和字符串的排序机制有关,暂不分析
这个时候我们可以使用正则表达式:
import re
lst.sort(key=lambda l: int(re.findall('\d+', l)[0])) # 找出字符串中的数字并依据其整形进行排序
print(lst)
# result = ['pic-1', 'pic-2', 'pic-3', 'pic-6', 'pic-10'] # 符合预期按顺序排序
用正则很容易将这个位置的序号“取出来”,转换为数字类型,然后利用sorted函数的第2个参数key进行排序即可。
比如本例可以用这样的代码进行排序:
folders = sorted(folders, key=lambda s: int(s.split()[-2]))
但是这样的算法并不够“干净”也不够“通用”,比如当文本中没有数字就会报错,或者数字不在规则设定的位置、或者有多组数字,也无法正确排序。
3.2 啊
既然没有捷径可走,那就想办法把所有的“数字”和“非数字字符”(不仅是英文)全部提出来。
比如目标字符串,目标达到这样的效果:
'he11owor1d' -> ['he', 11, 'owor', 1, 'd']
可以使用正则表达式进行匹配,不过正则表达式中,"\d+“只能匹配数字,”\D+“只能匹配非数字,”(\D+)(\d+)"可以取出所有的数字和非数字,但是却匹配不到字符串首的数字和字符串尾的非数字。
为了解决这一点,手动在串首和串尾分别增加一个英文和数字,就可以让原本字符串内的所有内容全部符合正则规则并匹配到,最后再删掉头尾就可以了。
(当然,头尾统一增加一个字符并不会影响排序顺序,所以这两个字符也可以不删)
正则表达式匹配:
s = 'he11owor1d' #hexxo,两个像l的为数字1
s1 = re.findall(r'(\D+)(\d+)', 'a' + s + '0') # 最后一个为数字0,\D匹配非数字,\d匹配数字
输出:
[('ahe', '11'), ('owor', '1'), ('d', '0')]
返回的结果是二维数组,通过sum函数组装成一维数组:
s2 = sum(s1, ())
输出:
('ahe', '11', 'owor', '1', 'd', '0')
这个很秀的操作是使用了sum函数的第2个控制参数:
sum(iterable, start=0, /)Return the sum of a ‘start’ value (default: 0) plus an iterable of numbersWhen the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types.
将数组中表示数字的字符串转化成数字,写成列表递推式可以用一行代码写出来:
s3 = [int(s) if s.isdigit() else s for s in s2]
输出:
['ahe', 11, 'owor', 1, 'd', 0]
一行代码写出来:
print(sorted(os.listdir(), key=lambda s: [int(s) if s.isdigit() else s for s in sum(re.findall(r'(\D+)(\d+)', 'a'+s+'0'), ())]))
print(sorted(os.listdir(), key=lambda s: [int(s) if s.isdigit() else s for s in re.findall(r'\D+|\d+', 'a'+s+'0')]))
print(sorted(os.listdir(), key=lambda s: sum(((s, int(n)) for s, n in re.findall(r'(\D+)(\d+)', 'a%s0'%s)), ())))
这个方法减少了n次str.isdigit()函数的运算,所以理论上还会更快一些。
另一方面为了增加代码的复用性
,还可以写成这样的两行:
fns = lambda s: sum(((s,int(n))for s,n in re.findall('(\D+)(\d+)','a%s0'%s)),())
print(sorted(os.listdir(), key=fns))
4. 列表
参考资料
[1] 用一行Python代码实现按字符串内数字大小排列字符串顺序 2021.8