我尝试了很多以自己的方式对 DataFrame 列进行排序。但无法正确地做到这一点。所以请参考给定的代码,让我知道完成这项工作的附加语法是什么。
df = pd.DataFrame({'TC': {0: '1-1.1', 1: '1-1.2', 2: '1-10.1', 3: '1-10.2', 4: '1-2.1', 5: '1-2.1', 6: '1-2.2', 7: '1-20.1', 8: '1-20.2', 9: '1-3.1'}, 'Case': {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J'}})
df.sort_values(["TC"], ascending=[True])
print (df)
这段代码没有给出想要的输出。我需要按以下方式排序的数据框。
答案 0 :(得分:5)
您可以提取数字并形成一个 tuple
,然后对该 series
进行排序并使用其 index
来 reindex
您的原始 DataFrame。
>>> df.reindex(
df['TC'].str.extractall('(\d+)')
.unstack().astype(int)
.agg(tuple, 1).sort_values()
.index
)
TC Case
0 1-1.1 A
1 1-1.2 B
4 1-2.1 E
5 1-2.1 F
6 1-2.2 G
9 1-3.1 J
2 1-10.1 C
3 1-10.2 D
7 1-20.1 H
8 1-20.2 I
您还可以在 key
中使用 sort_values
参数:
>>> df.sort_values('TC',
key=lambda ser:
ser.str.extractall('(\d+)')
.unstack()
.astype(int).agg(tuple, 1)
)
如果 ID
总是有三部分,你可以在 Series.str.split
字符上使用 non-numeric
和 expand=True
,而不是 extractall
,因此不需要使用 unstack
:
>>> df.sort_values('TC',
key=lambda series:
series.str.split(r'\D+', expand=True)
.astype(int).agg(tuple,1)
)
时间:
>>> %timeit df.reindex(df['TC'].str.extractall('(\d+)').unstack().astype(int).agg(tuple, 1).sort_values().index)
2.95 ms ± 40.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit df.sort_values('TC', key=lambda ser: ser.str.extractall('(\d+)').unstack().astype(int).agg(tuple, 1))
2.91 ms ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit df.sort_values('TC', key=lambda series:series.str.split(r'\D+', expand=True).astype(int).agg(tuple,1))
1.6 ms ± 5.88 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
答案 1 :(得分:1)
我会这样做的。我认为这会更快。
df["range"] = df["TC"].apply(lambda x: [float(y) for y in x.split("-")])
df = df.sort_values(["range"], ascending=True).drop(["range"], axis="columns")
编辑: 并且由于您要求范围的格式为 1_1_2 代替 1-1.2 的情况,因此我会这样做:
df["range"] = df["TC"].apply(lambda x: tuple(x.split("_")))
df["range"] = df["range"].apply(lambda x: [float(x[0]), float("{}.{}".format(x[1], x[2]))])
df = df.sort_values(["range"], ascending=True).drop(["range"], axis="columns")
答案 2 :(得分:0)
我制作了一个 sort() 函数来解决您的查询。
import pandas as pd
df = pd.DataFrame({'TC': {0: '1-1.1', 1: '1-1.2', 2: '1-10.1', 3: '1-10.2', 4: '1-2.1', 5: '1-2.1', 6: '1-2.2', 7: '1-20.1', 8: '1-20.2', 9: '1-3.1'}, 'Case': {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J'}})
def sort(df):
listTC=[]
for i in df['TC']:
listTC.append(float(i[2:]))
df1=pd.DataFrame(list(zip(listTC,list(df['Case']))),columns=['TC','Case'])
df_f=df1.sort_values(by=['TC'])
listTC_final=[]
for i in df_f['TC']:
listTC_final.append('1-'+str(i))
df_Final=pd.DataFrame(list(zip(listTC_final,list(df_f['Case']))),columns=['TC','Case'])
return df_Final
print(sort(df))
如果有任何问题,请告诉我。 谢谢