python - 从 Python 中的子组获取基本统计信息
问题描述
我正在使用 Python 3.6,并且正在尝试从数据集的子组中获取统计信息。例如,主要的分组因素是Uni
和year
。从那里,我想从其他子组获得一些基本统计数据,例如,女性人数或参加科学课程的学生人数及其比例。
进行直接计数的风险是可能存在一些重复计数。我已经解决了重复计算问题,但是代码似乎太长了,考虑到有成千上万的学生和更多的大学和年份,第一次分组需要很长时间。我希望那里有其他更有效的答案。
df1 = pd.DataFrame([('USC', 2009, 'A', 'X', 'Science', 'F', 50),
('USC', 2009, 'A', 'Y', 'Science', 'F', 50),
('USC', 2009, 'A', 'Z', 'Arts', 'F', 500),
('USC', 2009, 'A', 'W', 'Arts', 'F', 50),
('USC', 2009, 'B', 'W', 'Arts', 'M', 500),
('USC', 2009, 'B', 'Z', 'Arts', 'M', 50),
('USC', 2009, 'C', 'X', 'Science', 'F', 50),
('USC', 2009, 'C', 'Y', 'Science', 'F', 500),
('USC', 2009, 'C', 'W', 'Arts', 'F', 50),
('USC', 2010, 'D', 'X', 'Science', 'M', 50),
('USC', 2010, 'D', 'Y', 'Science', 'M', 500),
('USC', 2010, 'D', 'W', 'Arts', 'M', 50),
('USC', 2010, 'E', 'X', 'Science', 'M', 50),
('USC', 2010, 'E', 'Y', 'Science', 'M', 500),
('USC', 2010, 'E', 'W', 'Arts', 'M', 50)],
columns=('Uni', 'year', 'student','course','faculty','gender', 'fee'))
用于编译最终数据的复杂代码是:
# first grouping - eliminating duplicities
data_tmp = df1.groupby(['Uni', 'year','student'])
data_gds = data_tmp.agg({'fee': 'sum'})
data_prc = (data_gds
.join(data_tmp['gender'].apply(lambda x: 1 if (x[x == 'F'].count()>0) else 0))
.join(data_tmp['faculty'].apply(lambda x: 1 if (x[x == 'Science'].count()>0) else 0 ))
.reset_index()
)
# second grouping - eliminating students
data_tmp = data_prc.groupby(['Uni', 'year'])
data_gds = data_tmp['student'].apply(lambda x: x.unique().shape[0]).to_frame('Num_student')
data_prc = (data_gds
.join(data_tmp.agg({'fee': 'sum'}))
.join(data_tmp.agg({'gender': 'sum'}).rename(columns={'gender': 'gender_female'}) )
.join(data_tmp.agg({'faculty':'sum'}).rename(columns={'faculty': 'faculty_Science'}))
.reset_index()
)
# adding percetages here
data_prc['Prc_Female'] = data_prc['gender_female']/data_prc['Num_student']
data_prc['Prc_Science'] = data_prc['faculty_Science']/data_prc['Num_student']
另外,我真的不需要使用费用总和,但似乎使用聚合允许我使用连接。似乎加入语句需要更长的时间,我希望有一种方法可以避免使用它们(或使其更好)。
解决方案
我们可以大大简化您当前的代码,也没有必要lambdas
。
def make_stats(df):
base = df.groupby(['Uni', 'year'], as_index=False) \
.agg({'student': pd.Series.nunique, 'fee': sum}) \
.rename(columns={'student': 'num_student'})
females = df[df.gender == 'F'].groupby(['Uni', 'year'], as_index=False) \
.agg({'student': pd.Series.nunique}) \
.rename(columns={'student': 'gender_female'})
science = df[df.faculty == 'Science'].groupby(['Uni', 'year'], as_index=False) \
.agg({'course': pd.Series.nunique}) \
.rename(columns={'course': 'faculty_science'})
kwargs = {'how': 'left',
'left_on': ['Uni', 'year'],
'right_on': ['Uni', 'year']}
step_1 = pd.merge(base, females, **kwargs)
step_2 = pd.merge(step_1, science, **kwargs).fillna(0)
step_2['prc_female'] = step_2['gender_female'] / step_2['num_student']
step_2['prc_science'] = step_2['faculty_science'] / step_2['num_student']
return step_2
output = make_stats(df1)
print(output)
Uni year num_student fee gender_female faculty_science prc_female prc_science
0 USC 2009 3 1800 2.0 2 0.666667 0.666667
1 USC 2010 2 1200 0.0 2 0.000000 1.000000
推荐阅读
- hyperledger-fabric - 如何在使用 fabric-mock-stub 测试链码时模拟两个链码
- c# - 从 Xamarin 表单中的 Listview 获取检查值
- java - java- ClassCastException- BigInt 不能转换为 Long
- centos - 坚持配置清漆
- bootstrap-4 - Bootstrap:不需要的手风琴行为
- git - 尝试将我的文件从 git 推送到 github 时出现错误,并发生此错误
- javascript - 如何使用外部 div 元素的 Onclick 事件
- go - 无论我是否关闭频道,地图缩小都不起作用
- c# - Linq 在同一个表中具有 case 条件,并在 where 条件下从其他表中计数
- mongodb - 无法对 Kubernetes 上的 mongodb 隐藏成员进行身份验证,“身份验证失败。”