Bir sütunun ay adını içerdiği python pandas veri çerçevem var.
Sözlük kullanarak nasıl özel sıralama yapabilirim, örneğin:
custom_dict = {'March':0, 'April':1, 'Dec':3}
Bir sütunun ay adını içerdiği python pandas veri çerçevem var.
Sözlük kullanarak nasıl özel sıralama yapabilirim, örneğin:
custom_dict = {'March':0, 'April':1, 'Dec':3}
Yanıtlar:
Pandas 0.15 , bunu yapmanın çok daha net bir yolunu sağlayan Kategorik Serisi'ni tanıttı :
Önce ay sütununu kategorik yapın ve kullanılacak sıralamayı belirtin.
In [21]: df['m'] = pd.Categorical(df['m'], ["March", "April", "Dec"])
In [22]: df # looks the same!
Out[22]:
a b m
0 1 2 March
1 5 6 Dec
2 3 4 April
Şimdi, ay sütununu sıraladığınızda, bu listeye göre sıralanacaktır:
In [23]: df.sort_values("m")
Out[23]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
Not: Listede bir değer yoksa, NaN'ye dönüştürülür.
İlgilenenler için daha eski bir cevap ...
Bir ara seri oluşturabilirsiniz ve bunun set_index
üzerine:
df = pd.DataFrame([[1, 2, 'March'],[5, 6, 'Dec'],[3, 4, 'April']], columns=['a','b','m'])
s = df['m'].apply(lambda x: {'March':0, 'April':1, 'Dec':3}[x])
s.sort_values()
In [4]: df.set_index(s.index).sort()
Out[4]:
a b m
0 1 2 March
1 3 4 April
2 5 6 Dec
Daha yeni pandalarda belirtildiği gibi, Series'in replace
bunu daha zarif bir şekilde yapmak için bir yöntemi vardır :
s = df['m'].replace({'March':0, 'April':1, 'Dec':3})
Küçük fark, sözlüğün dışında bir değer varsa bunun artmamasıdır (sadece aynı kalacaktır).
s = df['m'].replace({'March':0, 'April':1, 'Dec':3})
2. satır için de çalışıyor - sadece benim gibi pandaları öğrenen herkesin hatırı için
.apply({'March':0, 'April':1, 'Dec':3}.get)
:) 0.15'te Kategorik Serilerimiz / sütunlarımız olacak, bu yüzden en iyi yol onu kullanmak ve sonra sıralama işe yarayacak.
df.sort_values("m")
Yeni pandalarda (yerine df.sort("m")
) kullandığınızdan emin olun , aksi takdirde bir AttributeError: 'DataFrame' object has no attribute 'sort'
;) elde edersiniz
Yakında argüman sort_values
ile kullanabileceksiniz key
:
pd.__version__
# '1.1.0.dev0+2004.g8d10bfb6f'
custom_dict = {'March': 0, 'April': 1, 'Dec': 3}
df
a b m
0 1 2 March
1 5 6 Dec
2 3 4 April
df.sort_values(by=['m'], key=lambda x: x.map(custom_dict))
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
key
Argüman girişi bir Serisi ve getiri Seri olarak sürer. Bu dizi dahili olarak sıralanmıştır ve sıralanan dizinler DataFrame girişini yeniden sıralamak için kullanılır. Sıralanacak birden fazla sütun varsa, anahtar işlevi sırayla her birine uygulanacaktır. Bkz . Anahtarlarla sıralama .
Basit bir yöntem çıktısını kullanarak bir Series.map
ve Series.argsort
içine indeksine df
kullanılarak DataFrame.iloc
(argsort sıralanmış bir tamsayı pozisyonları ürettiği için); bir sözlüğünüz olduğu için; bu kolaylaşır.
df.iloc[df['m'].map(custom_dict).argsort()]
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
Azalan sırada sıralamanız gerekiyorsa , eşlemeyi ters çevirin.
df.iloc[(-df['m'].map(custom_dict)).argsort()]
a b m
1 5 6 Dec
2 3 4 April
0 1 2 March
Bunun yalnızca sayısal öğeler üzerinde çalıştığını unutmayın. Aksi takdirde, sort_values
dizini kullanarak ve bu dizine erişerek bu sorunu çözmeniz gerekecektir :
df.loc[df['m'].map(custom_dict).sort_values(ascending=False).index]
a b m
1 5 6 Dec
2 3 4 April
0 1 2 March
astype
(Bu artık kullanımdan kaldırılmıştır) veya ile daha fazla seçenek mevcuttur pd.Categorical
, ancak doğruordered=True
çalışması için belirtmeniz gerekir .
# Older version,
# df['m'].astype('category',
# categories=sorted(custom_dict, key=custom_dict.get),
# ordered=True)
df['m'] = pd.Categorical(df['m'],
categories=sorted(custom_dict, key=custom_dict.get),
ordered=True)
Şimdi, basit bir sort_values
arama hile yapacak:
df.sort_values('m')
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
Kategorik sıralama groupby
, çıktıları sıralarken de dikkate alınacaktır .
ordered=None
Varsayılan olarak Kategorik kümeler . Ayarlanmazsa, sıralama yanlış olacaktır veya V23'te bozulacaktır. Maks işlevi özellikle bir TypeError verir (Kategorik, maks. İşlem için sıralanmaz).
seçilen cevabı kullanın ! bu gönderiden daha yenidir ve yalnızca pandalarda sıralı verileri korumanın resmi yolu değildir, her açıdan daha iyidir, özellikler / performans vb. dahil. Aşağıda tarif ettiğim hacky yöntemimi kullanmayın.
Bu güncellemeyi sadece insanlar cevabımı yükseltmeye devam ettikleri için yazıyorum, ancak kesinlikle kabul edilenden daha kötü :)
Oyuna biraz geç kaldınız, ancak pandaların Series, DataFrame ve multiindex DataFrame nesnelerini rastgele işlevler kullanarak sıralayan bir işlev oluşturmanın bir yolu.
I faydalanmak df.iloc[index]
(göre konumuna göre bir serisi / DataFrame bir satır başvuran yöntem, df.loc
ki referanslar değeri). Bunu kullanarak, bir dizi konumsal argüman döndüren bir işleve sahip olmamız yeterlidir:
def sort_pd(key=None,reverse=False,cmp=None):
def sorter(series):
series_list = list(series)
return [series_list.index(i)
for i in sorted(series_list,key=key,reverse=reverse,cmp=cmp)]
return sorter
Bunu, özel sıralama işlevleri oluşturmak için kullanabilirsiniz. Bu, Andy Hayden'ın cevabında kullanılan veri çerçevesi üzerinde çalışır:
df = pd.DataFrame([
[1, 2, 'March'],
[5, 6, 'Dec'],
[3, 4, 'April']],
columns=['a','b','m'])
custom_dict = {'March':0, 'April':1, 'Dec':3}
sort_by_custom_dict = sort_pd(key=custom_dict.get)
In [6]: df.iloc[sort_by_custom_dict(df['m'])]
Out[6]:
a b m
0 1 2 March
2 3 4 April
1 5 6 Dec
Bu, multiindex DataFrames ve Series nesnelerinde de çalışır:
months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
df = pd.DataFrame([
['New York','Mar',12714],
['New York','Apr',89238],
['Atlanta','Jan',8161],
['Atlanta','Sep',5885],
],columns=['location','month','sales']).set_index(['location','month'])
sort_by_month = sort_pd(key=months.index)
In [10]: df.iloc[sort_by_month(df.index.get_level_values('month'))]
Out[10]:
sales
location month
Atlanta Jan 8161
New York Mar 12714
Apr 89238
Atlanta Sep 5885
sort_by_last_digit = sort_pd(key=lambda x: x%10)
In [12]: pd.Series(list(df['sales'])).iloc[sort_by_last_digit(df['sales'])]
Out[12]:
2 8161
0 12714
3 5885
1 89238
Bana göre bu temiz hissettiriyor, ancak optimize edilmiş pandaların işlemlerine güvenmek yerine yoğun bir şekilde python işlemlerini kullanıyor. Herhangi bir stres testi yapmadım ama bunun çok büyük DataFrame'lerde yavaşlayabileceğini tahmin ediyorum. Performansın sütun ekleme, sıralama ve silme işlemine kıyasla nasıl olduğundan emin değilsiniz. Kodu hızlandırmak için herhangi bir ipucu takdir edilecektir!
df.sort_index()
dizininiz varsa, bunları tercih ettiğiniz sıralama düzenine göre düzenleyin ve ardından tüm dizin düzeylerini sıralamak için kullanın .
import pandas as pd
custom_dict = {'March':0,'April':1,'Dec':3}
df = pd.DataFrame(...) # with columns April, March, Dec (probably alphabetically)
df = pd.DataFrame(df, columns=sorted(custom_dict, key=custom_dict.get))
March, April, Dec sütunlarına sahip bir DataFrame döndürür