Bir Pandas veri çerçevesinde minimum değeri bulun ve yeni sütuna bir etiket ekleyin
Python pandalarımın kodunu daha verimli hale getirmek için ne tür iyileştirmeler yapabilirim? Benim durumum için bu veri çerçevesine sahibim
In [1]: df = pd.DataFrame({'PersonID': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'Name': ["Jan", "Jan", "Jan", "Don", "Don", "Don", "Joe", "Joe", "Joe"],
'Label': ["REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL"],
'RuleID': [55, 55, 55, 3, 3, 3, 10, 10, 10],
'RuleNumber': [3, 4, 5, 1, 2, 3, 234, 567, 999]})
Bu sonucu veren:
In [2]: df
Out[2]:
PersonID Name Label RuleID RuleNumber
0 1 Jan REL 55 3
1 1 Jan REL 55 4
2 1 Jan REL 55 5
3 2 Don REL 3 1
4 2 Don REL 3 2
5 2 Don REL 3 3
6 3 Joe REL 10 234
7 3 Joe REL 10 567
8 3 Joe REL 10 999
Burada gerçekleştirmem gereken şey, bir Kişi Kimliği ve Adına uygulanan her Kural Kimliği ile ilişkili en düşük kural değeri için Etiket sütununun altındaki alanları ANA olarak güncellemektir. Bu nedenle, sonuçların şöyle görünmesi gerekir:
In [3]: df
Out[3]:
PersonID Name Label RuleID RuleNumber
0 1 Jan MAIN 55 3
1 1 Jan REL 55 4
2 1 Jan REL 55 5
3 2 Don MAIN 3 1
4 2 Don REL 3 2
5 2 Don REL 3 3
6 3 Joe MAIN 10 234
7 3 Joe REL 10 567
8 3 Joe REL 10 999
Bunu başarmak için yazdığım kod bu:
In [4]:
df['Label'] = np.where(
df['RuleNumber'] ==
df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].transform('min'),
"MAIN", df.Label)
Etiket sütununun altındaki değerleri güncellemenin daha iyi bir yolu var mı? Kendimi zorlayarak zorladığımı hissediyorum ve bunu yapmanın en etkili yolu bu olmayabilir.
Sonucuma ulaşmak için aşağıdaki SO konularını kullandım:
Bir grup ve koşul içindeki sütun değerlerini değiştirin
Bir grup içindeki değerleri birden çok koşula göre değiştirin
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.idxmin.html
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.transform.html
Gruplandırılmış Satırların Minimum Değerlerini Bulmak İçin Pandaları Kullanma
Herhangi bir tavsiye memnuniyetle karşılanacaktır.
Teşekkür ederim.
Yanıtlar
Görünüşe göre gruplandırılmış idxminsıraya bakılmaksızın filtreleyebilir ve buna göre güncelleme yapabilirsiniz RuleNumber. Sen kullanabilirsiniz loc, np.where, mask, veya whereaşağıdaki gibi:
df.loc[df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].idxmin(), 'Label'] = 'MAIN'
VEYA np.wheredenediğiniz gibi:
df['Label'] = (np.where((df.index == df.groupby(['PersonID', 'Name', 'RuleID'])
['RuleNumber'].transform('idxmin')), 'MAIN', 'REL'))
df
Out[1]:
PersonID Name Label RuleID RuleNumber
0 1 Jan MAIN 55 3
1 1 Jan REL 55 4
2 1 Jan REL 55 5
3 2 Don MAIN 3 1
4 2 Don REL 3 2
5 2 Don REL 3 3
6 3 Joe MAIN 10 234
7 3 Joe REL 10 567
8 3 Joe REL 10 999
Kullanmak maskveya tersi wherede işe yarar :
df['Label'] = (df['Label'].mask((df.index == df.groupby(['PersonID', 'Name', 'RuleID'])
['RuleNumber'].transform('idxmin')), 'MAIN'))
VEYA
df['Label'] = (df['Label'].where((df.index != df.groupby(['PersonID', 'Name', 'RuleID'])
['RuleNumber'].transform('idxmin')), 'MAIN'))
import pandas as pd
df = pd.DataFrame({'PersonID': [1, 1, 1, 2, 2, 2, 3, 3, 3],
'Name': ["Jan", "Jan", "Jan", "Don", "Don", "Don", "Joe", "Joe", "Joe"],
'Label': ["REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL", "REL"],
'RuleID': [55, 55, 55, 3, 3, 3, 10, 10, 10],
'RuleNumber': [3, 4, 5, 1, 2, 3, 234, 567, 999]})
df.loc[df.groupby('Name')['RuleNumber'].idxmin()[:], 'Label'] = 'MAIN'
duplicatedKişi Kimliğinde kullanın :
df.loc[~df['PersonID'].duplicated(),'Label'] = 'MAIN'
print(df)
Çıktı:
PersonID Name Label RuleID RuleNumber
0 1 Jan MAIN 55 3
1 1 Jan REL 55 4
2 1 Jan REL 55 5
3 2 Don MAIN 3 1
4 2 Don REL 3 2
5 2 Don REL 3 3
6 3 Joe MAIN 10 234
7 3 Joe REL 10 567
8 3 Joe REL 10 999