I'm new to pandas and moving from sql. I have a problem, where I'm trying to replace sql-case when statements with pandas At a high level, I have a input data frame and a reference table. I create computed columns based on the ref. table Example Input data ------------+-----------+----+------------+-----+------+ |
STUDENT_ID | UG_MAJOR | C1 | C2 | C3 | C4 |
+------------+-----------+----+------------+-----+------+
| 123 | MATH | A | 8000-10000 | 12% | 9000 |
| 234 | ALL_OTHER | B | 1500-2000 | 10% | 1500 |
| 345 | ALL_OTHER | A | 2800-3000 | 8% | 2300 |
| 456 | ALL_OTHER | A | 8000-10000 | 12% | 3200 |
| 980 | ALL_OTHER | C | 1000-2500 | 15% | 2700 |
+------------+-----------+----+------------+-----+------+
Ref Data
---------+---------+---------+
| REF_COL | REF_VAL | REF_SCR |
+---------+---------+---------+
| C1 | A | 10 |
| C1 | B | 20 |
| C1 | C | 30 |
| C1 | NULL | 0 |
| C1 | MISSING | 0 |
| C1 | A | 20 |
| C1 | B | 30 |
| C1 | C | 40 |
| C1 | NULL | 10 |
| C1 | MISSING | 10 |
| C2 | <1000 | 0 |
| C2 | >1000 | 20 |
| C2 | >7000 | 30 |
| C2 | >9500 | 40 |
| C2 | MISSING | 0 |
| C2 | NULL | 0 |
| C3 | <3% | 5 |
| C3 | >3% | 10 |
| C3 | >5% | 100 |
| C3 | >7% | 200 |
| C3 | >10% | 300 |
| C3 | NULL | 0 |
| C3 | MISSING | 0 |
| C4 | <5000 | 10 |
| C4 | >5000 | 20 |
| C4 | >10000 | 30 |
| C4 | >15000 | 40 |
+---------+---------+---------+
----------+-----------+----+------------+-----+------+--------+--------+--------+---------+
| Req.Output | | | | | | | | | |
+------------+-----------+----+------------+-----+------+--------+--------+--------+---------+
| STUDENT_ID | UG_MAJOR | C1 | C2 | C3 | C4 | C1_SCR | C2_SCR | C3_SCR | TOT_SCR |
| 123 | MATH | A | 8000-10000 | 12% | 9000 | | | | |
| 234 | ALL_OTHER | B | 1500-2000 | 10% | 1500 | | | | |
| 345 | ALL_OTHER | A | 2800-3000 | 8% | 2300 | | | | |
| 456 | ALL_OTHER | A | 8000-10000 | 12% | 3200 | | | | |
| 980 | ALL_OTHER | C | 1000-2500 | 15% | 2700 | | | | |
+------------+-----------+----+------------+-----+------+--------+--------+--------+---------+
Traditional SQL way is
select student_id,
UG_MAJOR,
C1,
case
when UG_MAJOR ='MATH' AND when C1 IS NULL THEN 0
when UG_MAJOR ='MATH' AND when C1 ='MISSING' THEN 0
when UG_MAJOR ='MATH' AND when C1 ='A' THEN 10
when UG_MAJOR ='MATH' AND when C1 ='B' THEN 20
when UG_MAJOR ='MATH' AND when C1 ='C' THEN 30
when UG_MAJOR ='ALL_OTHER' AND when C1 IS NULL THEN 0
when UG_MAJOR ='ALL_OTHER' AND when C1 ='MISSING' THEN 0
when UG_MAJOR ='ALL_OTHER' AND when C1 ='A' THEN 20
when UG_MAJOR ='ALL_OTHER' AND when C1 ='B' THEN 30
when UG_MAJOR ='ALL_OTHER' AND when C1 ='C' THEN 40
ELSE 'TBD' END AS C1_SCR,
C2,
CASE
WHEN C2 IS NULL THEN 0
WHEN C2 ='Missing' OR C2 = . THEN 0
WHEN C2<=1000 THEN 0
WHEN C2 >1000 AND C2<=7000 THEN 20
WHEN C2 >7000 AND C2<=9500 THEN 30
WHEN C2 >9500 THEN 40
ELSE 'TBD'
END AS C2_SCR
FROM REF_INPUT
GROUP BY 1,2,3,4,5,6
I'm wondering if there is an elegant way to handle in pandas ? Thanks Par
As mentioned in a few comments above I made a few assumptions in creating this solution since a few things were not provided but here is my attempt at returning the requested df even if it is not elegant...
dfc = df.copy()
dfc['c1_scr'] = 'TBD'
dfc = dfc.loc[((dfc.ug_major=='MATH')&(dfc.c1.isnull()))
|((dfc.ug_major=='MATH')&(dfc.c1=='Missing'))
|((dfc.ug_major=='ALL_OTHER')&(dfc.c1=='Missing'))
|((dfc.ug_major=='MATH')&(dfc.c1.isnull())),
'c1_scr'] = 0
dfc = dfc.loc[((dfc.ug_major=='MATH')&(dfc.c1=='A')),'c1_scr'] = 10
dfc = dfc.loc[((dfc.ug_major=='MATH')&(dfc.c1=='B'))
|((dfc.ug_major=='ALL_OTHER')&(dfc.c1=='A'))
,'c1_scr'] = 20
dfc = dfc.loc[((dfc.ug_major=='MATH')&(dfc.c1=='C'))
|((dfc.ug_major=='ALL_OTHER')&(dfc.c1=='A'))
,'c1_scr'] = 30
dfc = dfc.loc[((dfc.ug_major=='ALL_OTHER')&(dfc.c1=='C')),'c1_scr'] = 40
dfc['c2_scr'] = 'TBD'
dfc = dfc.loc[(dfc.c2.isnull())
|(dfc.c2=='MISSING')
|(dfc.c2=='.')
|(dfc.c2<=1000)
,'c2_scr'] = 0
dfc = dfc.loc[(dfc.c2>1000)
&(dfc.c2<=7000)
,'c2_scr'] = 20
dfc = dfc.loc[(dfc.c2>7000)
&(dfc.c2<=9500)
,'c2_scr'] = 30
dfc = dfc.loc[(dfc.c2>9500),'c2_scr'] = 40
dfc = dfc[['student_id','ug_major','c1','c1_scr'
,'c2','c2_scr']
].groupby(['student_id','ug_major','c1','c1_scr','c2','c2_scr'])
print(dfc.head())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.