我在工作中遇到了一个与排序有关的问题。我目前正在使用熊猫来保存我们的数据,我需要对包含数字和定界符的字符串的列进行排序。
我已经尝试在要排序的列上使用vanilla df.sort_values('Field Name'),但是发生了一些不需要的结果。
以Python格式采样数据:
import pandas as pd
lis=[]
for i in ['99','100','101','102']:
for j in map(str,[1,2,3,4,5,6,7,8,10,20,22,21,34]):
for k in map(str,[1,2,11,12,22,23,33,16,17]):
lis.append(i+'_'+j+'-'+k)
y = pd.DataFrame(dict(Field=lis))
y.sort_values('Field')
示例输出:
Field
0 100_1-1
1 100_1-11
2 100_1-12
3 100_1-16
4 100_1-17
5 100_1-2
6 100_1-22
7 100_1-23
8 100_1-33
9 100_10-1
10 100_10-11
11 100_10-12
12 100_10-16
13 100_10-17
14 100_10-2
15 100_10-22
16 100_10-23
17 100_10-33
18 100_2-1
19 100_2-11
20 100_2-12
21 100_2-16
22 100_2-17
....
从中可以看到,列表应以“ 99”字符串开头。另外,您在100_1-2之前有100_1-11、100_1-12、100_1-13。
我可以使用以下方法解决第一个问题,理论上,如果我知道先验的定界符和定界符的数量,那么我可以迭代地继续这样做,直到获得所需的结果为止。
y.reindex(y['Field'].str.split('_',1,expand=True)[0].astype(int).sort_values(0).index).reset_index(drop=True)
但是由于定界符'_'和'-'可能会被使用,所以不一定要在我收到的数据中使用它们,也不知道只有2个定界符。因此,从理论上讲,我可能会遇到以下问题:
100_1_22-12-34:5
我仍然需要能够按预期对它们进行排序。
但是,有没有一种方法可以使用Pandas以更通用的形式获得我想要的结果?需要明确的是,我希望所有数字都按预期排列,并使用尽可能少的代码。
答案 0 :(得分:2)
在将所有各种字符分割后,需要将字符串数字转换为整数。使用 int 元组进行排序:
您可以这样做像这样:
import pandas as pd
lis=[]
# mix up numbers / strings and values
for i in ['103','99','102','101']:
for j in map(str,[10,2,34,4,5,1,22,21,3]):
for k in map(str,[1,2,33,16,17]):
lis.append(i+'_'+j+'-'+k)
df = pd.DataFrame(dict(Field=lis))
# split mixed up stuff using regex ('-' first so it does NOT denote a char-range)
# convert all remainders to int and make them a tuple to sort on (seperate column)
df["tup"] = df["Field"].str.split(r"[-_:]").apply(lambda x: tuple(map(int, x)))
# sort on seperate column
df = df.sort_values("tup")
print(df)
输出:
[180 rows x 1 columns]
Field tup
70 99_1-1 (99, 1, 1)
71 99_1-2 (99, 1, 2)
73 99_1-16 (99, 1, 16)
74 99_1-17 (99, 1, 17)
72 99_1-33 (99, 1, 33)
50 99_2-1 (99, 2, 1)
51 99_2-2 (99, 2, 2)
53 99_2-16 (99, 2, 16)
54 99_2-17 (99, 2, 17)
.. ... ...
34 103_22-17 (103, 22, 17)
32 103_22-33 (103, 22, 33)
10 103_34-1 (103, 34, 1)
11 103_34-2 (103, 34, 2)
13 103_34-16 (103, 34, 16)
14 103_34-17 (103, 34, 17)
12 103_34-33 (103, 34, 33)
[180 rows x 2 columns]
排序前:
Field
0 103_10-1
1 103_10-2
2 103_10-33
3 103_10-16
4 103_10-17
5 103_2-1
.. ...
173 101_21-16
174 101_21-17
175 101_3-1
176 101_3-2
177 101_3-33
178 101_3-16
179 101_3-17