पंडों के डेटाफ्रेम में न्यूनतम मूल्य ज्ञात करें और नए कॉलम पर एक लेबल जोड़ें

Dec 18 2020

अपने पायथन पांडा कोड को और अधिक कुशल बनाने के लिए मैं क्या सुधार कर सकता हूं? मेरे मामले के लिए, मेरे पास यह डेटाफ़्रेम है

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

जो यह परिणाम देता है:

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

यहां मुझे जो कुछ भी पूरा करने की आवश्यकता है, वह है लेबल कॉलम कॉलम के तहत MAIN के लिए न्यूनतम नियम मान जो कि एक व्यक्ति आईडी और नाम पर लागू होता है, से जुड़े न्यूनतम नियम मूल्य के लिए फ़ील्ड को अद्यतन करना। इसलिए, परिणामों को इस तरह देखना होगा:

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

यह वह कोड है जिसे मैंने इसे पूरा करने के लिए लिखा था:

In [4]:

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

क्या लेबल कॉलम के तहत मूल्यों को अपडेट करने का एक बेहतर तरीका है? मुझे लगता है कि मैं अपने रास्ते के लिए मजबूर कर रहा हूँ और यह ऐसा करने का सबसे कारगर तरीका नहीं हो सकता है।

मैंने अपने परिणाम पर पहुंचने के लिए निम्नलिखित SO थ्रेड्स का उपयोग किया:

समूह मान और स्थिति में स्तंभ मान बदलें

कई शर्तों के आधार पर एक समूह के भीतर मान बदलें

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

पंडों का उपयोग समूहबद्ध पंक्तियों के न्यूनतम मूल्यों का पता लगाने के लिए

किसी भी सलाह की सराहना की जाएगी।

धन्यवाद।

जवाब

1 DavidErickson Dec 18 2020 at 03:14

ऐसा लगता है कि आप idxminक्रमबद्ध क्रम और अद्यतन के RuleNumberआधार पर समूहीकृत करके फ़िल्टर कर सकते हैं । आप उपयोग कर सकते हैं loc, np.where, mask, या whereइस प्रकार है:

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

या np.whereजैसा कि आप कोशिश कर रहे थे:

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

उपयोग maskया इसके उलटा whereभी काम करेगा:

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

या

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

व्यक्ति पर प्रयोग करें duplicated:

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

आउटपुट:

   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