[英]Sort Pandas DataFrame by string column that represents (mostly) numbers?
我有類似的數據。
data = [
dict(name = 'test1', index = '1' , status='fail'),
dict(name = 'test3', index = '3', status='pass'),
dict(name = 'test1', index = '11', status='pass'),
dict(name = 'test1', index = '1 2 14 56', status='fail'),
dict(name = 'test3', index = '20', status='fail'),
dict(name = 'test1', index = '2' , status='fail'),
dict(name = 'test3', index = '5:1:50', status='pass'),]
請注意,“索引”列的類型是 str。 由於它有一些不規則的條目,我不能輕易地將其轉換為數字類型。 (如果這是可能的,我不會有這個問題。)
首先,我將其轉換為 DataFrame:
df = pd.DataFrame(data)
這給了我
name index status
0 test1 1 fail
1 test3 3 pass
2 test1 11 pass
3 test1 1 2 14 56 fail
4 test3 20 fail
5 test1 2 fail
6 test3 5:1:50 pass
接下來我對其進行排序:
df1 = df.sort_values(by=['name','index'])
由於 'index' 列是 'str',它將按詞法排序。
name index status
0 test1 1 fail
3 test1 1 2 14 56 fail
2 test1 11 pass
5 test1 2 fail
4 test3 20 fail
1 test3 3 pass
6 test3 5:1:50 pass
我真正想要的是:
name index status
0 test1 1 fail
5 test1 2 fail
2 test1 11 pass
3 test1 1 2 14 56 fail
1 test3 3 pass
4 test3 20 fail
6 test3 5:1:50 pass
第 4 行和第 7 行(DF 索引 3 和 6)中的不規則值也可以 go 到每個測試組的開頭。 關鍵點是,可以轉換為數字表示的“索引”列的值應按數字排序。 最好就地。 如何?
一種可能性是創建一個列,該列將為您提供索引的長度。
df['sort'] = df['index'].str.len()
df['sort2'] = df['index'].str[0]
df1 = df.sort_values(by=['name','sort','sort2'])
df1 = df1.drop(columns = ['sort','sort2'])
這將按名稱和臨時列 ( __ix
) 排序,該列是在每個'index'
字符串中找到的第一個 integer (連續數字):
更新:您還可以使用:
df = (
df
.assign(
__ix=df['index'].str.extract(r'([0-9]+)').astype(int)
)
.sort_values(['name', '__ix'])
.drop('__ix', axis=1) # optional: remove the tmp column
.reset_index(drop=True) # optional: leaves the index scrambled
)
原文:
df = (
df
.assign(
__ix=df['index']
.apply(lambda s: int(re.match(r'\D*(\d+)', s).group(0)))
)
.sort_values(['name', '__ix'])
.drop('__ix', axis=1)
.reset_index(drop=True)
)
在您的數據上(感謝您提供了一個簡單的可重現示例),首先檢查__ix
列是什么:
df['index'].apply(lambda s: int(re.match(r'\D*(\d+)', s).group(0)))
# out:
0 1
1 3
2 11
3 1
4 20
5 2
6 5
排序后,您的 df 變為:
name index status
0 test1 1 fail
1 test1 1 2 14 56 fail
2 test1 2 fail
3 test1 11 pass
4 test3 3 pass
5 test3 5:1:50 pass
6 test3 20 fail
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.