动机
与大多数人一样,我开始学习数据科学时使用的第一个工具是Jupyter Notebook。大多数在线数据科学课程都使用Jupyter Notebook作为教学手段。这是有道理的,因为对于初学者来说,在Jupyter Notebook的单元格中开始编写代码比编写具有类和函数的脚本要容易得多。
Jupyter Notebook之所以成为数据科学中如此普遍的工具的另一个原因是,Jupyter Notebook使其易于浏览和绘制数据。当我们输入“ Shift + Enter”时,我们将立即看到代码的结果,这使我们很容易确定我们的代码是否有效。
但是,当我处理更多数据科学项目时,我意识到了Jupyter Notebook的一些后备功能:
我知道必须有一种更好的方式来处理我的代码,所以我决定尝试一下脚本。这些是我在使用脚本时发现的好处:
有组织的
Jupyter Notebook中的单元格使得很难将代码组织成不同的部分。使用脚本,我们可以创建几个小函数,每个函数指定代码的功能,如下所示
更好的是,如果可以将这些函数归为同一类,例如处理数据的函数,我们可以将它们归为同一类!
每当我们要处理数据时,我们都知道该类中的函数Preprocess
可用于此目的。
当我们想尝试另一种预处理数据的方法时,我们可以通过注释掉这样的方式来添加或删除函数,而不必担心破坏代码!即使我们碰巧破坏了代码,我们也知道在哪里修复它。
我们还可以通过更改函数的输入来试验不同的参数。例如,如果我们想看看对Pandas系列重新采样的不同方法如何影响我的结果,我们可以从切换method_of_resample='sum’
到method_of_resample= 'average'
。多么整洁!
使用类和函数,我们可以使代码足够通用,以便能够与其他数据一起使用。
例如,如果我们想在新数据中删除不同的列,我们只需要更改columns_to_drop
为要删除的列的列表,代码就可以平稳运行!
columns_to_drop = config.columns.to_drop
datetime_column = config.columns.datetime.sentiment
dropna_columns = config.columns.drop_na
processor = Preprocess(columns_to_drop, datetime_column, dropna_columns)
使用函数,可以更轻松地测试该函数是否产生我们期望的输出。我们可以快速找出应该在代码中更改的位置以产生所需的输出。
def extract_date_hour_minute(string: str):
'''Extract data hour and minute from datetime string'''
try:
return string[:16]
except TypeError:
return np.nan
def test_extract_date_hour_minute():
'''Test whether the function extract date, hour, and minute '''
string = '2020-07-30T23:25:31.036+03:00'
assert extract_date_hour_minute(string) == '2020-07-30T23:25'
或添加配置文件以控制变量的值。这样可以避免我们浪费时间跟踪代码中的特定变量以更改其值。
from preprocess import preprocess
from model import run_model
from predict import predict
def main(config):
df = preprocess(config)
df = run_model(config)
df, df_scale, min_day, max_day, accuracy = predict(df, config)
我们还可以很容易地添加工具来跟踪实验。
如果您刚刚从Jupyter Notebook切换到脚本,那么用脚本编写代码可能并不直观,但是请相信我,您最终会习惯使用脚本。
一旦发生这种情况,相对于凌乱的Jupyter Notebook,您将开始认识到脚本的许多优点,并希望在脚本中编写大部分代码。
话虽如此,Jupyter Notebook仍可用于探索和可视化数据。您可以在脚本中创建类和函数,然后将其导入笔记本中,以使笔记本不那么混乱。但是请注意不要过度使用笔记本,尤其是当您要将代码投入生产时。
如果您对较大的变化不满意,请从小做起。
大变化始于小步。