Temukan nilai minimum dalam bingkai data Pandas dan tambahkan label pada kolom baru

Dec 18 2020

Perbaikan apa yang dapat saya lakukan pada kode python pandas saya agar lebih efisien? Untuk kasus saya, saya memiliki kerangka data ini

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]})

Yang memberikan hasil ini:

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

Yang perlu saya capai di sini adalah memperbarui bidang di bawah kolom Label ke MAIN untuk nilai aturan terendah yang terkait dengan setiap ID Aturan yang diterapkan ke ID dan Nama Orang. Oleh karena itu, hasilnya perlu terlihat seperti ini:

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

Ini adalah kode yang saya tulis untuk mencapai ini:

In [4]:

df['Label'] = np.where(
        df['RuleNumber'] ==
        df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].transform('min'),
        "MAIN", df.Label)

Apakah ada cara yang lebih baik untuk memperbarui nilai di bawah kolom Label? Saya merasa seperti saya kasar memaksa saya dan ini mungkin bukan cara yang paling efisien untuk melakukan ini.

Saya menggunakan utas SO berikut untuk sampai pada hasil saya:

Ganti nilai kolom dalam groupby dan condition

Ganti nilai dalam grup berdasarkan pada beberapa kondisi

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

Menggunakan Panda untuk Menemukan Nilai Minimum dari Baris yang Dikelompokkan

Saran apa pun akan dihargai.

Terima kasih.

Jawaban

1 DavidErickson Dec 18 2020 at 03:14

Sepertinya Anda dapat memfilter berdasarkan yang dikelompokkan idxminterlepas dari urutan yang diurutkan dan memperbarui RuleNumberberdasarkan itu. Anda dapat menggunakan loc, np.where, mask, atau wheresebagai berikut:

df.loc[df.groupby(['PersonID', 'Name', 'RuleID'])['RuleNumber'].idxmin(), 'Label'] = 'MAIN'

ATAU dengan np.wheresaat Anda mencoba:

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

Menggunakan maskatau kebalikannya wherejuga akan berfungsi:

df['Label'] = (df['Label'].mask((df.index == df.groupby(['PersonID', 'Name', 'RuleID'])
                         ['RuleNumber'].transform('idxmin')), 'MAIN'))

ATAU

df['Label'] = (df['Label'].where((df.index != df.groupby(['PersonID', 'Name', 'RuleID'])
                         ['RuleNumber'].transform('idxmin')), 'MAIN'))
1 Scared Dec 18 2020 at 03:25
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'
ScottBoston Dec 18 2020 at 03:45

Gunakan duplicateddi PersonID:

df.loc[~df['PersonID'].duplicated(),'Label'] = 'MAIN'
print(df)

Keluaran:

   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