最简单的方法是对具有多个列的数据框进行子集查找,并找到与查询匹配的行数。
有没有更简单的方法来重写以下代码。
目标是查找获得所有季度成绩的学生人数和仅错过第四季度成绩的学生人数。
resDataFrame = df[(df['6th-Grade-Q1'] == 'Y') & (df['6th-Grade-Q2'] == 'Y' ) & (df['6th-Grade-Q3'] == 'Y') & (df['6th-Grade-Q4'] == 'Y') ]
numberOfStudents = len(resDataFrame.index)
resDataFrame = df[ (df['6th-Grade-Q1'] == 'Y') & (df['6th-Grade-Q2'] == 'Y' ) & (df['6th-Grade-Q3'] == 'Y') & (df['6th-Grade-Q4'] == 'X') ]
numberOfStudentsMissed = len(resDataFrame.index)
答案 0 :(得分:1)
您的第一行可以大大缩短,因为条件始终相同,并且列名遵循以下模式:
df.filter(like='6th-Grade-Q').eq('Y').all(1).sum()
如果除{4}以外的其他以'6th-Grade-Q'
开头的列,请不要使用filter并在列表中明确指定4列。对于第二种情况,您可以使用:
(df[['6th-Grade-Q1', '6th-Grade-Q2', '6th-Grade-Q3']].eq('Y').all(1) & df['6th-Grade-Q4'].eq('X')).sum()
由于只需要计数,因此无需对原始DataFrame
进行子集运算,然后再计算长度。只需将掩码的True
值相加即可。
如果您想要一个更通用的解决方案来检查许多&
运算符之间不遵循模式的相等条件之间的条件,则退回到numpy
。首先指定要作为元组检查的列和相等性的列表:
import numpy as np
condlist = [('6th-Grade-Q1', 'Y'), ('6th-Grade-Q2', 'Y'),
('6th-Grade-Q3', 'Y'), ('6th-Grade-Q4', 'Y')]
np.logical_and.reduce([df[col].eq(val) for col,val in condlist]).sum()