这是如何建立数据科学作品集系列文章中的第一篇。如果你喜欢这篇文章并且想知道此系列的下一篇文章何时发表,你可以在页面底部订阅[1]。
数据科学公司们在决定雇佣一个人时越来越看重其作品集。其中一个原因就是作品集是分析一个人真实技能的最好方式。好消息是,作品集是完全可以被你掌控的。如果你在其上投入了一些工作,你就能够做出一个令那些公司印象深刻的作品集结果。
建立一个高质量作品集的第一步就是知道展示什么技能。那些公司们主要希望数据科学工作者拥有的技能,或者说他们主要希望作品集所展示的技能是:
任何一个好的作品集都由多个工程构成,每一个工程都会展示 1-2 个上面所说的点。这是涵盖了“如何完成一个完整的数据科学作品集”系列文章的第一篇。在这篇文章中,我们将会涵括如何完成你的第一项数据科学作品集工程,并且对此进行有效的解释。在最后,你将会得到一个帮助展示你表达能力和解释数据能力的工程。
用数据讲故事
数据科学是表达的基础。你将会在数据中发现一些观点,并且找出一个高效的方式来向他人表达这些,之后向他们展示你所开展的课题。数据科学最关键的手法之一就是能够用数据讲述一个清晰的故事。一个清晰的故事能够使你的观点更加引人注目,并且能使别人理解你的想法。
数据科学中的故事是一个讲述你发现了什么,你怎么发现它的,并且它意味着什么的故事。例如假使发现你公司的收入相对去年减少了百分之二十。这并不能够确定原因,你可能需要和其它人沟通为什么收入会减少,并且在尝试修复它。
用数据讲故事主要包含:
用来讲述数据的故事最有效率的工具就是 Jupyter notebook[2]。如果你不熟悉,此处[3]有一个好的教程。Jupyter notebook 允许你交互式的发掘数据,并且将你的结果分享到多个网站,包括 Github。分享你的结果有助于合作研究和其他人拓展你的分析。
在这篇文章中,我们将使用 Jupyter notebook,以及 Pandas 和 matplotlib 这样的 Python 库。
为你的数据科学工程选择一个主题
建立一个工程的第一步就是决定你的主题。你要让你的主题是你兴趣所在,有动力去挖掘。进行数据挖掘时,为了完成而完成和有兴趣完成的区别是很明显的。这个步骤是值得花费时间的,所以确保你找到了你真正感兴趣的东西。
一个寻找主题的好方法就是浏览不同的数据集并且寻找感兴趣的部分。这里有一些作为起点的好的网站:
真实世界中的数据科学,你经常无法找到可以浏览的合适的单个数据集。你可能需要聚合多个独立的数据源,或者做数量庞大的数据清理。如果该主题非常吸引你,这是值得这样做的,并且也能更好的展示你的技能。
关于这篇文章的主题,我们将使用纽约市公立学校的数据,我们可以在这里[8]找到它。
选择主题
这对于项目全程来说是十分重要的。因为主题能很好的限制项目的范围,并且它能够使我们知道它可以被完成。比起一个没有足够动力完成的工程来说,添加到一个完成的工程更加容易。
所以,我们将关注高中的学术评估测试[9],伴随着多种人口统计和它们的其它数据。关于学习评估测试, 或者说 SAT,是美国高中生申请大学前的测试。大学在做判定时将考虑该成绩,所以高分是十分重要的。考试分为三个阶段,每个阶段总分为 800。全部分数为 2400(即使这个前后更改了几次,在数据中总分还是 2400)。高中经常通过平均 SAT分数进行排名,并且 SAT 是评判高中有多好的标准。
因为由关于 SAT 分数对于美国中某些种族群体是不公平的,所以对纽约市这个数据做分析能够对 SAT 的公平性有些许帮助。
我们在这里[10]有 SAT 成绩的数据集,并且在这里[11]有包含了每所高中的信息的数据集。这些将构成我们的工程的基础,但是我们将加入更多的信息来创建有趣的分析。
补充数据
如果你已经有了一个很好的主题,拓展其它可以提升主题或者更深入挖掘数据的的数据集是一个好的选择。在前期十分适合做这些工作,你将会有尽可能多的数据来构建你的工程。数据越少意味着你会太早的放弃了你的工程。
在本项目中,在包含人口统计信息和测试成绩的网站上有一些相关的数据集。
这些是我们将会用到的所有数据集:
(LCTT 译注:高阶位考试(AP)是美国和加拿大的一个由大学委员会创建的计划,该计划为高中学生提供大学水平的课程和考试。 美国学院和大学可以授予在考试中获得高分的学生的就学和课程学分。)
这些数据作品集之间是相互关联的,并且我们能够在开始分析之前进行合并。
获取背景信息
在开始分析数据之前,搜索一些背景信息是有必要的。我们知道这些有用的信息:
理解数据
为了真正的理解数据信息,你需要花费时间来挖掘和阅读数据。因此,每个数据链接都有数据的描述信息,并伴随着相关列。就像是我们拥有的高中 SAT 成绩信息,也包含图像和其它信息的数据集。
我们可以运行一些代码来读取数据。我们将使用 Jupyter notebook[20] 来挖掘数据。下面的代码将会执行以下操作:
In [100]:
import pandas
import numpy as np
files = ["ap_2010.csv", "class_size.csv", "demographics.csv", "graduation.csv", "hs_directory.csv", "math_test_results.csv", "sat_results.csv"]
data = {}
for f in files:
d = pandas.read_csv("schools/{0}".format(f))
data[f.replace(".csv", "")] = d
一旦我们将数据读入,我们就可以使用 DataFrames 的 head[22] 方法打印每个 DataFrame 的前五行。
In [103]:
for k,v in data.items():
print("\n" + k + "\n")
print(v.head())
math_test_results
DBN Grade Year Category Number Tested Mean Scale Score Level 1 # \
0 01M015 3 2006 All Students 39 667 2
1 01M015 3 2007 All Students 31 672 2
2 01M015 3 2008 All Students 37 668 0
3 01M015 3 2009 All Students 33 668 0
4 01M015 3 2010 All Students 26 677 6
Level 1 % Level 2 # Level 2 % Level 3 # Level 3 % Level 4 # Level 4 % \
0 5.1% 11 28.2% 20 51.3% 6 15.4%
1 6.5% 3 9.7% 22 71% 4 12.9%
2 0% 6 16.2% 29 78.4% 2 5.4%
3 0% 4 12.1% 28 84.8% 1 3%
4 23.1% 12 46.2% 6 23.1% 2 7.7%
Level 3+4 # Level 3+4 %
0 26 66.7%
1 26 83.9%
2 31 83.8%
3 29 87.9%
4 8 30.8%
ap_2010
DBN SchoolName AP Test Takers \
0 01M448 UNIVERSITY NEIGHBORHOOD H.S. 39
1 01M450 EAST SIDE COMMUNITY HS 19
2 01M515 LOWER EASTSIDE PREP 24
3 01M539 NEW EXPLORATIONS SCI,TECH,MATH 255
4 02M296 High School of Hospitality Management s
Total Exams Taken Number of Exams with scores 3 4 or 5
0 49 10
1 21 s
2 26 24
3 377 191
4 s s
sat_results
DBN SCHOOL NAME \
0 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL STUDIES
1 01M448 UNIVERSITY NEIGHBORHOOD HIGH SCHOOL
2 01M450 EAST SIDE COMMUNITY SCHOOL
3 01M458 FORSYTH SATELLITE ACADEMY
4 01M509 MARTA VALLE HIGH SCHOOL
Num of SAT Test Takers SAT Critical Reading Avg. Score SAT Math Avg. Score \
0 29 355 404
1 91 383 423
2 70 377 402
3 7 414 401
4 44 390 433
SAT Writing Avg. Score
0 363
1 366
2 370
3 359
4 384
class_size
CSD BOROUGH SCHOOL CODE SCHOOL NAME GRADE PROGRAM TYPE \
0 1 M M015 P.S. 015 Roberto Clemente 0K GEN ED
1 1 M M015 P.S. 015 Roberto Clemente 0K CTT
2 1 M M015 P.S. 015 Roberto Clemente 01 GEN ED
3 1 M M015 P.S. 015 Roberto Clemente 01 CTT
4 1 M M015 P.S. 015 Roberto Clemente 02 GEN ED
CORE SUBJECT (MS CORE and 9-12 ONLY) CORE COURSE (MS CORE and 9-12 ONLY) \
0 - -
1 - -
2 - -
3 - -
4 - -
SERVICE CATEGORY(K-9* ONLY) NUMBER OF STUDENTS / SEATS FILLED \
0 - 19.0
1 - 21.0
2 - 17.0
3 - 17.0
4 - 15.0
NUMBER OF SECTIONS AVERAGE CLASS SIZE SIZE OF SMALLEST CLASS \
0 1.0 19.0 19.0
1 1.0 21.0 21.0
2 1.0 17.0 17.0
3 1.0 17.0 17.0
4 1.0 15.0 15.0
SIZE OF LARGEST CLASS DATA SOURCE SCHOOLWIDE PUPIL-TEACHER RATIO
0 19.0 ATS NaN
1 21.0 ATS NaN
2 17.0 ATS NaN
3 17.0 ATS NaN
4 15.0 ATS NaN
demographics
DBN Name schoolyear fl_percent frl_percent \
0 01M015 P.S. 015 ROBERTO CLEMENTE 20052006 89.4 NaN
1 01M015 P.S. 015 ROBERTO CLEMENTE 20062007 89.4 NaN
2 01M015 P.S. 015 ROBERTO CLEMENTE 20072008 89.4 NaN
3 01M015 P.S. 015 ROBERTO CLEMENTE 20082009 89.4 NaN
4 01M015 P.S. 015 ROBERTO CLEMENTE 20092010 96.5
total_enrollment prek k grade1 grade2 ... black_num black_per \
0 281 15 36 40 33 ... 74 26.3
1 243 15 29 39 38 ... 68 28.0
2 261 18 43 39 36 ... 77 29.5
3 252 17 37 44 32 ... 75 29.8
4 208 16 40 28 32 ... 67 32.2
hispanic_num hispanic_per white_num white_per male_num male_per female_num \
0 189 67.3 5 1.8 158.0 56.2 123.0
1 153 63.0 4 1.6 140.0 57.6 103.0
2 157 60.2 7 2.7 143.0 54.8 118.0
3 149 59.1 7 2.8 149.0 59.1 103.0
4 118 56.7 6 2.9 124.0 59.6 84.0
female_per
0 43.8
1 42.4
2 45.2
3 40.9
4 40.4
[5 rows x 38 columns]
graduation
Demographic DBN School Name Cohort \
0 Total Cohort 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL 2003
1 Total Cohort 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL 2004
2 Total Cohort 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL 2005
3 Total Cohort 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL 2006
4 Total Cohort 01M292 HENRY STREET SCHOOL FOR INTERNATIONAL 2006 Aug
Total Cohort Total Grads - n Total Grads - % of cohort Total Regents - n \
0 5 s s s
1 55 37 67.3% 17
2 64 43 67.2% 27
3 78 43 55.1% 36
4 78 44 56.4% 37
Total Regents - % of cohort Total Regents - % of grads \
0 s s
1 30.9% 45.9%
2 42.2% 62.8%
3 46.2% 83.7%
4 47.4% 84.1%
... Regents w/o Advanced - n \
0 ... s
1 ... 17
2 ... 27
3 ... 36
4 ... 37
Regents w/o Advanced - % of cohort Regents w/o Advanced - % of grads \
0 s s
1 30.9% 45.9%
2 42.2% 62.8%
3 46.2% 83.7%
4 47.4% 84.1%
Local - n Local - % of cohort Local - % of grads Still Enrolled - n \
0 s s s s
1 20 36.4% 54.1% 15
2 16 25% 37.200000000000003% 9
3 7 9% 16.3% 16
4 7 9% 15.9% 15
Still Enrolled - % of cohort Dropped Out - n Dropped Out - % of cohort
0 s s s
1 27.3% 3 5.5%
2 14.1% 9 14.1%
3 20.5% 11 14.1%
4 19.2% 11 14.1%
[5 rows x 23 columns]
hs_directory
dbn school_name boro \
0 17K548 Brooklyn School for Music & Theatre Brooklyn
1 09X543 High School for Violin and Dance Bronx
2 09X327 Comprehensive Model School Project M.S. 327 Bronx
3 02M280 Manhattan Early College School for Advertising Manhattan
4 28Q680 Queens Gateway to Health Sciences Secondary Sc... Queens
building_code phone_number fax_number grade_span_min grade_span_max \
0 K440 718-230-6250 718-230-6262 9 12
1 X400 718-842-0687 718-589-9849 9 12
2 X240 718-294-8111 718-294-8109 6 12
3 M520 718-935-3477 NaN 9 10
4 Q695 718-969-3155 718-969-3552 6 12
expgrade_span_min expgrade_span_max \
0 NaN NaN
1 NaN NaN
2 NaN NaN
3 9 14.0
4 NaN NaN
... \
0 ...
1 ...
2 ...
3 ...
4 ...
priority02 \
0 Then to New York City residents
1 Then to New York City residents who attend an ...
2 Then to Bronx students or residents who attend...
3 Then to New York City residents who attend an ...
4 Then to Districts 28 and 29 students or residents
priority03 \
0 NaN
1 Then to Bronx students or residents
2 Then to New York City residents who attend an ...
3 Then to Manhattan students or residents
4 Then to Queens students or residents
priority04 priority05 \
0 NaN NaN
1 Then to New York City residents NaN
2 Then to Bronx students or residents Then to New York City residents
3 Then to New York City residents NaN
4 Then to New York City residents NaN
priority06 priority07 priority08 priority09 priority10 \
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN
Location 1
0 883 Classon Avenue\nBrooklyn, NY 11225\n(40.67...
1 1110 Boston Road\nBronx, NY 10456\n(40.8276026...
2 1501 Jerome Avenue\nBronx, NY 10452\n(40.84241...
3 411 Pearl Street\nNew York, NY 10038\n(40.7106...
4 160-20 Goethals Avenue\nJamaica, NY 11432\n(40...
[5 rows x 58 columns]
我们可以开始在数据作品集中观察有用的部分:
Location 1
,这列在一个很长的字符串里面包含了位置信息。
统一数据
为了使工作更简单,我们将需要将全部零散的数据集统一为一个。这将使我们能够快速跨数据集对比数据列。因此,我们需要找到相同的列将它们统一起来。请查看上面的输出数据, DBN 出现在多个数据集中,它看起来可以作为共同列。
如果我们用 google 搜索 DBN New York City Schools
,我们在此[23]得到了结果。它解释了 DBN 是每个学校独特的编码。我们将挖掘数据集,特别是政府数据集。这通常需要做一些工作来找出每列的含义,或者每个数据集的意图。
现在主要的问题是这两个数据集 class_size
和 hs_directory
,没有 DBN
列。在 hs_directory
数据中是 dbn
,那么我们只需重命名即可,或者将它复制到新的名为 DBN 的列中。在 class_size
数据中,我们将需要尝试不同的方法。
DBN 列:
In [5]:
data["demographics"]["DBN"].head()
Out[5]:
0 01M015
1 01M015
2 01M015
3 01M015
4 01M015
Name: DBN, dtype: object
如果我们查看 class_size
数据,我们将看到前五行如下:
In [4]:
data["class_size"].head()
Out[4]:
CSD | BOROUGH | SCHOOL CODE | SCHOOL NAME | GRADE | PROGRAM TYPE | CORE SUBJECT (MS CORE and 9-12 ONLY) | CORE COURSE (MS CORE and 9-12 ONLY) | SERVICE CATEGORY(K-9* ONLY) | NUMBER OF STUDENTS / SEATS FILLED | NUMBER OF SECTIONS | AVERAGE CLASS SIZE | SIZE OF SMALLEST CLASS | SIZE OF LARGEST CLASS | DATA SOURCE | SCHOOLWIDE PUPIL-TEACHER RATIO | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | M | M015 | P.S. 015 Roberto Clemente | 0K | GEN ED | - | - | - | 19.0 | 1.0 | 19.0 | 19.0 | 19.0 | ATS | NaN |
1 | 1 | M | M015 | P.S. 015 Roberto Clemente | 0K | CTT | - | - | - | 21.0 | 1.0 | 21.0 | 21.0 | 21.0 | ATS | NaN |
2 | 1 | M | M015 | P.S. 015 Roberto Clemente | 01 | GEN ED | - | - | - | 17.0 | 1.0 | 17.0 | 17.0 | 17.0 | ATS | NaN |
3 | 1 | M | M015 | P.S. 015 Roberto Clemente | 01 | CTT | - | - | - | 17.0 | 1.0 | 17.0 | 17.0 | 17.0 | ATS | NaN |
4 | 1 | M | M015 | P.S. 015 Roberto Clemente | 02 | GEN ED | - | - | - | 15.0 | 1.0 | 15.0 | 15.0 | 15.0 | ATS | NaN |
正如上面所见,DBN 实际上是 CSD
、 BOROUGH
和 SCHOOL CODE
的组合。对那些不熟悉纽约市的人来说,纽约由五个行政区组成。每个行政区是一个组织单位,并且有着相当于美国大城市一样的面积。DBN 全称为行政区域编号。看起来就像 CSD 是区域,BOROUGH 是行政区,并且当与 SCHOOL CODE 合并时就组成了 DBN。这里并没有寻找像这个数据这样的内在规律的系统方法,这需要一些探索和努力来发现。
现在我们已经知道了 DBN 的组成,那么我们就可以将它加入到 class_size
和 hs_directory
数据集中了:
In [ ]:
data["class_size"]["DBN"] = data["class_size"].apply(lambda x: "{0:02d}{1}".format(x["CSD"], x["SCHOOL CODE"]), axis=1)
data["hs_directory"]["DBN"] = data["hs_directory"]["dbn"]
加入问卷
最可能值得一看的数据集之一就是学生、家长和老师关于学校质量的问卷了。这些问卷包含了每所学校的安全程度、教学水平等。在我们合并数据集之前,让我们添加问卷数据。在真实世界的数据科学工程中,你经常会在分析过程中碰到有趣的数据,并且希望合并它。使用像 Jupyter notebook 一样灵活的工具将允许你快速添加一些新的代码,并且重新开始你的分析。
因此,我们将添加问卷数据到我们的 data 文件夹,并且合并所有之前的数据。问卷数据分为两个文件,一个包含所有的学校,一个包含 75 学区。我们将需要写一些代码来合并它们。之后的代码我们将:
In [66]:
survey1 = pandas.read_csv("schools/survey_all.txt", delimiter="\t", encoding='windows-1252')
survey2 = pandas.read_csv("schools/survey_d75.txt", delimiter="\t", encoding='windows-1252')
survey1["d75"] = False
survey2["d75"] = True
survey = pandas.concat([survey1, survey2], axis=0)
一旦我们将问卷合并,这里将会有一些混乱。我们希望我们合并的数据集列数最少,那么我们将可以轻易的进行列之间的对比并找出其间的关联。不幸的是,问卷数据有很多列并不是很有用:
In [16]:
survey.head()
Out[16]:
N_p | N_s | N_t | acap11 | acas11 | acat11 | acatot11 | bn | comp11 | coms11 | ... | tq8c1 | tq8c2 | tq8c3 | tq8c4 | t_q9 | tq91 | tq92 | tq93 | tq94 | tq95 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 90.0 | NaN | 22.0 | 7.8 | NaN | 7.9 | 7.9 | M015 | 7.6 | NaN | ... | 29.0 | 67.0 | 5.0 | 0.0 | NaN | 5.0 | 14.0 | 52.0 | 24.0 | 5.0 |
1 | 161.0 | NaN | 34.0 | 7.8 | NaN | 9.1 | 8.4 | M019 | 7.6 | NaN | ... | 74.0 | 21.0 | 6.0 | 0.0 | NaN | 3.0 | 6.0 | 3.0 | 78.0 | 9.0 |
2 | 367.0 | NaN | 42.0 | 8.6 | NaN | 7.5 | 8.0 | M020 | 8.3 | NaN | ... | 33.0 | 35.0 | 20.0 | 13.0 | NaN | 3.0 | 5.0 | 16.0 | 70.0 | 5.0 |
3 | 151.0 | 145.0 | 29.0 | 8.5 | 7.4 | 7.8 | 7.9 | M034 | 8.2 | 5.9 | ... | 21.0 | 45.0 | 28.0 | 7.0 | NaN | 0.0 | 18.0 | 32.0 | 39.0 | 11.0 |
4 | 90.0 | NaN | 23.0 | 7.9 | NaN | 8.1 | 8.0 | M063 | 7.9 | NaN | ... | 59.0 | 36.0 | 5.0 | 0.0 | NaN | 10.0 | 5.0 | 10.0 | 60.0 | 15.0 |
5 rows × 2773 columns
我们可以通过查看数据文件夹中伴随问卷数据下载下来的文件来解决这个问题。它告诉我们们数据中重要的部分是哪些:
我们可以去除 survey
数据集中多余的列:
In [17]:
survey["DBN"] = survey["dbn"]
survey_fields = ["DBN", "rr_s", "rr_t", "rr_p", "N_s", "N_t", "N_p", "saf_p_11", "com_p_11", "eng_p_11", "aca_p_11", "saf_t_11", "com_t_11", "eng_t_10", "aca_t_11", "saf_s_11", "com_s_11", "eng_s_11", "aca_s_11", "saf_tot_11", "com_tot_11", "eng_tot_11", "aca_tot_11",]
survey = survey.loc[:,survey_fields]
data["survey"] = survey
survey.shape
Out[17]:
(1702, 23)
请确保理你已经了解了每个数据集的内容和相关联的列,这能节约你之后大量的时间和精力:
精简数据集
如果我们查看某些数据集,包括 class_size
,我们将立刻发现问题:
In [18]:
data["class_size"].head()
Out[18]:
CSD | BOROUGH | SCHOOL CODE | SCHOOL NAME | GRADE | PROGRAM TYPE | CORE SUBJECT (MS CORE and 9-12 ONLY) | CORE COURSE (MS CORE and 9-12 ONLY) | SERVICE CATEGORY(K-9* ONLY) | NUMBER OF STUDENTS / SEATS FILLED | NUMBER OF SECTIONS | AVERAGE CLASS SIZE | SIZE OF SMALLEST CLASS | SIZE OF LARGEST CLASS | DATA SOURCE | SCHOOLWIDE PUPIL-TEACHER RATIO | DBN | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | M | M015 | P.S. 015 Roberto Clemente | 0K | GEN ED | - | - | - | 19.0 | 1.0 | 19.0 | 19.0 | 19.0 | ATS | NaN | 01M015 |
1 | 1 | M | M015 | P.S. 015 Roberto Clemente | 0K | CTT | - | - | - | 21.0 | 1.0 | 21.0 | 21.0 | 21.0 | ATS | NaN | 01M015 |
2 | 1 | M | M015 | P.S. 015 Roberto Clemente | 01 | GEN ED | - | - | - | 17.0 | 1.0 | 17.0 | 17.0 | 17.0 | ATS | NaN | 01M015 |
3 | 1 | M | M015 | P.S. 015 Roberto Clemente | 01 | CTT | - | - | - | 17.0 | 1.0 | 17.0 | 17.0 | 17.0 | ATS | NaN | 01M015 |
4 | 1 | M | M015 | P.S. 015 Roberto Clemente | 02 | GEN ED | - | - | - | 15.0 | 1.0 | 15.0 | 15.0 | 15.0 | ATS | NaN | 01M015 |
每所高中都有许多行(正如你所见的重复的 DBN
和 SCHOOL NAME
)。然而,如果我们看向 sat_result
数据集,每所高中只有一行:
In [21]:
data["sat_results"].head()
Out[21]:
DBN | SCHOOL NAME | Num of SAT Test Takers | SAT Critical Reading Avg. Score | SAT Math Avg. Score | SAT Writing Avg. Score | |
---|---|---|---|---|---|---|
0 | 01M292 | HENRY STREET SCHOOL FOR INTERNATIONAL STUDIES | 29 | 355 | 404 | 363 |
1 | 01M448 | UNIVERSITY NEIGHBORHOOD HIGH SCHOOL | 91 | 383 | 423 | 366 |
2 | 01M450 | EAST SIDE COMMUNITY SCHOOL | 70 | 377 | 402 | 370 |
3 | 01M458 | FORSYTH SATELLITE ACADEMY | 7 | 414 | 401 | 359 |
4 | 01M509 | MARTA VALLE HIGH SCHOOL | 44 | 390 | 433 | 384 |
为了合并这些数据集,我们将需要找到方法将数据集精简到如 class_size
般一行对应一所高中。否则,我们将不能将 SAT 成绩与班级大小进行比较。我们通过首先更好的理解数据,然后做一些合并来完成。class_size
数据集像 GRADE
和 PROGRAM TYPE
,每个学校有多个数据对应。为了将每个范围内的数据变为一个数据,我们将大部分重复行过滤掉,在下面的代码中我们将会:
class_size
中选择
GRADE
范围为
09-12
的行。
class_size
中选择
PROGRAM TYPE
是
GEN ED
的行。
class_size
以
DBN
分组,然后取每列的平均值。重要的是,我们将找到每所学校班级大小(
class_size
)平均值。
DBN
重新加到列中。
In [68]:
class_size = data["class_size"]
class_size = class_size[class_size["GRADE "] == "09-12"]
class_size = class_size[class_size["PROGRAM TYPE"] == "GEN ED"]
class_size = class_size.groupby("DBN").agg(np.mean)
class_size.reset_index(inplace=True)
data["class_size"] = class_size
精简其它数据集
接下来,我们将需要精简 demographic
数据集。这里有每个学校收集多年的数据,所以这里每所学校有许多重复的行。我们将只选取 schoolyear
最近的可用行:
In [69]:
demographics = data["demographics"]
demographics = demographics[demographics["schoolyear"] == 20112012]
data["demographics"] = demographics
我们需要精简 math_test_results
数据集。这个数据集被 Grade
和 Year
划分。我们将只选取单一学年的一个年级。
In [70]:
data["math_test_results"] = data["math_test_results"][data["math_test_results"]["Year"] == 2011]
data["math_test_results"] = data["math_test_results"][data["math_test_results"]["Grade"] == '8']
最后,graduation
需要被精简:
In [71]:
data["graduation"] = data["graduation"][data["graduation"]["Cohort"] == "2006"]
data["graduation"] = data["graduation"][data["graduation"]["Demographic"] == "Total Cohort"]
在完成工程的主要部分之前数据清理和挖掘是十分重要的。有一个高质量的,一致的数据集将会使你的分析更加快速。
(接下篇)
via: https://www.dataquest.io/blog/data-science-portfolio-project/
作者:Vik Paruchuri [35] 译者:[Yoo-4x] 校对:wxy
本文由 LCTT 原创编译,Linux中国 荣誉推出