标签: readability

将jupyter笔记本变成python脚本的最佳实践

Jupyter(iPython)笔记本当之无愧地被认为是一个很好的工具,用于对代码进行原型设计并以交互方式进行各种机器学习.但是当我使用它时,我不可避免地遇到以下问题:

  • 笔记本电脑很快就变得过于复杂和混乱而无法进行维护和改进,而且我必须制作python脚本;
  • 当涉及到生产代码(例如每天需要重新运行的代码)时,笔记本电脑再次不是最好的格式.

假设我在jupyter中开发了一个整机学习管道,包括从各种来源获取原始数据,清理数据,特征工程和培训模型.现在用高效可读的代码从中制作脚本的最佳逻辑是什么?到目前为止,我曾经用几种方法解决它:

  1. 只需将.ipynb转换为.py,只需稍加修改,就可以将笔记本中的所有管道硬编码为一个python脚本.

    • '+':快
    • ' - ':脏,不灵活,维护不方便
  2. 制作一个包含许多函数的单个脚本(对于每一个或两个单元格大约有1个函数),尝试使用单独的函数组成管道的各个阶段,并相应地命名它们.然后通过指定所有参数和全局常量argparse.

    • '+':使用更灵活; 更可读的代码(如果您正确地将管道逻辑转换为函数)
    • ' - ':通常情况下,管道不能拆分成逻辑上完成的部分,这些部分可以成为函数而代码中没有任何怪癖.所有这些函数通常只需要在脚本中调用一次,而不是在循环,映射等内多次调用.此外,每个函数通常都会获取之前调用的所有函数的输出,因此必须将多个参数传递给每个函数.功能.
  3. 与point(2)相同,但现在将所有函数包装在类中.现在,所有全局常量以及每个方法的输出都可以存储为类属性.

    • '+':您不需要为每个方法传递许多参数 - 所有以前的输出都已存储为属性
    • ' - ':任务的整体逻辑仍未被捕获 - 它是数据和机器学习管道,而不仅仅是类.该类的唯一目标是创建,逐个调用所有方法,然后删除.除此之外,课程实施起来还很长.
  4. 使用多个脚本将笔记本转换为python模块.我没有试过这个,但我怀疑这是解决这个问题的最长方法.

我想,这种整体设置在数据科学家中非常普遍,但令人惊讶的是我无法找到任何有用的建议.

伙计们,请分享您的想法和经验.你有没有遇到过这个问题?你是怎么解决它的?

python refactoring readability ipython-notebook jupyter

37
推荐指数
2
解决办法
8503
查看次数

特征:编码风格对性能的影响

从我读到的关于Eigen(这里)的内容来看,它似乎operator=()充当了懒惰评估的"障碍" - 例如它导致Eigen停止返回表达式模板并实际执行(优化的)计算,将结果存储到左边的=.

这似乎意味着一个人的"编码风格"对性能产生影响 - 即使用命名变量来存储中间计算的结果可能会对计算的某些部分进行"太早"评估,从而对性能产生负面影响. .

为了验证我的直觉,我写了一个例子并对结果感到惊讶(完整的代码在这里):

using ArrayXf  = Eigen::Array <float, Eigen::Dynamic, Eigen::Dynamic>;
using ArrayXcf = Eigen::Array <std::complex<float>, Eigen::Dynamic, Eigen::Dynamic>;

float test1( const MatrixXcf & mat )
{
    ArrayXcf arr  = mat.array();
    ArrayXcf conj = arr.conjugate();
    ArrayXcf magc = arr * conj;
    ArrayXf  mag  = magc.real();
    return mag.sum();
}

float test2( const MatrixXcf & mat )
{
    return ( mat.array() * mat.array().conjugate() ).real().sum();
}

float test3( const MatrixXcf & mat …
Run Code Online (Sandbox Code Playgroud)

c++ performance readability eigen

37
推荐指数
3
解决办法
3487
查看次数

"自我记录"如何编码而不会烦人?

我不确定这里的最佳实践是什么,但我经常看到缩写变量名称,尤其是当范围很小时.所以(使用简单的Ruby示例)而不是def add_location(name, coordinates),我看到类似的东西def add_loc(name, coord)- 我甚至可能会看到类似的东西def add_loc(n, x, y).我想,当他们习惯于看到缩写词时,较长的名字可能会让一个人厌倦.

冗长是否有助于提高可读性,还是只会伤害每个人的眼睛? - 人们更喜欢缩写和缩短名称吗?

ruby documentation readability

35
推荐指数
7
解决办法
2230
查看次数

StringBuilder/StringBuffer与"+"运算符

我正在阅读" 更好,更快,更轻的Java "(由Bruce Tate和Justin Gehtland撰写)并且熟悉敏捷类型团队的可读性要求,例如Robert Martin在其清晰的编码书中所讨论的内容.在我现在的团队中,我被告知明确不使用+运算符,因为它在运行时创建了额外的(和不必要的)字符串对象.

但是这篇文章,写于04年,讨论了对象分配是关于10个机器指令的.(基本上免费)

它还讨论了GC如何帮助降低此环境中的成本.

什么是使用之间的实际性能的权衡+,StringBuilder还是StringBuffer?(就我而言,它StringBuffer仅限于Java 1.4.2.)

StringBuffer对我来说导致丑陋,不太可读的代码,正如Tate的书中的几个例子所示.而且StringBuffer是线程同步的,这似乎有它自己的成本是大于中使用了"危险" +操作.

思想/意见?

java performance readability

35
推荐指数
3
解决办法
3万
查看次数

在JavaScript中编写多行字符串最简洁的方法是什么?

它实际上不必添加新行,只是可读的东西.

有什么比这更好的?

str = "line 1" +
      "line 2" +
      "line 3";
Run Code Online (Sandbox Code Playgroud)

javascript string maintainability readability

34
推荐指数
6
解决办法
2万
查看次数

Java try/catch性能,是否建议将try子句中的内容保持在最低限度?

考虑到你有这样的代码:

doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing the same kind of exceptions.
Run Code Online (Sandbox Code Playgroud)

现在我知道,实际上在构造异常时会出现性能损失,特别是展开堆栈.我还阅读了几篇文章,指出在输入try/catch块时会有轻微的性能损失,但这些文章似乎都没有结论.

我的问题是,是否建议将try catch中的行保持最小?,即只在try子句中包含可以实际抛出正在捕获的异常的行.try子句中的代码运行速度较慢或导致性能下降吗?

但考虑到这一点,更重要的是最佳实践/更易读的解决方案:

try {
    doSomething() // this method may throw a checked a exception
//do some assignements calculations
doAnotherThing() //this method may also throw the same type of checked exception
//more calls to methods and calculations, all throwing …
Run Code Online (Sandbox Code Playgroud)

java performance readability try-catch

33
推荐指数
2
解决办法
2万
查看次数

为什么STL实现如此难以理解?如何在这里改进C++?

比如为什么在STL实现大多数成员_M____前缀?为什么有那么多样板代码?

C++缺少哪些功能可以使make vector(例如)实现更清晰,更简洁?

c++ stl readability c++11

32
推荐指数
2
解决办法
4178
查看次数

哪个代码更具可读性?

假设我有两种方法bool Foo()bool Bar().以下哪项更具可读性?

if(Foo())
{
    SomeProperty = Bar();
}
else
{
    SomeProperty = false;
}
Run Code Online (Sandbox Code Playgroud)

要么

SomeProperty = Foo() && Bar();
Run Code Online (Sandbox Code Playgroud)

一方面,我认为短路&&是一个有用的功能,第二个代码样本要短得多.另一方面,我不确定人们通常习惯于&&在条件陈述之外看到,所以我想知道是否会引入一些认知失调,这使得第一个样本成为更好的选择.

你怎么看?还有其他影响决策的因素吗?比如,如果&&表达式长于可以放在屏幕上的一行,我应该更喜欢前者吗?


答案后澄清:

我应该把一些事情包括在答案提出的最初问题中.

  • Bar()可能比执行起来更昂贵Foo(),但这两种方法都不应该有副作用.
  • 这些方法都被更恰当地命名,而不是像这个例子中那样. Foo()归结为类似CurrentUserAllowedToDoX()Bar()更像是,XCanBeDone()

c# readability

32
推荐指数
7
解决办法
3687
查看次数

Python中的通用异常处理"正确的方法"

有时我发现自己处于需要执行多个顺序命令的情况:

try:
    foo(a, b)
except Exception, e:
    baz(e)
try:
    bar(c, d)
except Exception, e:
    baz(e)
...
Run Code Online (Sandbox Code Playgroud)

只需要忽略异常时就会出现相同的模式.

这感觉多余,并且过多的语法使得在阅读代码时难以理解.

在C中,我很容易用宏来解决这类问题,但不幸的是,这不能在直接的python中完成.

问题:在遇到这种模式时,如何才能最好地减少代码占用空间并提高代码可读性?

python readability exception

30
推荐指数
2
解决办法
5万
查看次数

在对象上调用getter而不是将其存储为局部变量(内存占用,性能)

在下面的代码中,我们进行了listType.getDescription()两次调用:

for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
    if (listType.getDescription() != null)
    {
        children.add(new SelectItem( listType.getId() , listType.getDescription()));
    }
}
Run Code Online (Sandbox Code Playgroud)

我倾向于重构代码以使用单个变量:

for (ListType listType: this.listTypeManager.getSelectableListTypes())
{
    String description = listType.getDescription();

    if (description != null)
    {
        children.add(new SelectItem(listType.getId() ,description));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的理解是JVM以某种方式针对原始代码进行了优化,尤其是嵌套调用children.add(new SelectItem(listType.getId(), listType.getDescription()));.

比较两个选项,哪一个是首选方法,为什么?这就是内存占用,性能,可读性/易用性以及其他我现在不想到的内容.

后一个代码片段何时变得比前者更有利,也就是说,listType.getDescription()当使用临时局部变量变得更加理想时,是否存在任何(近似)调用次数,因为listType.getDescription()总是需要一些堆栈操作来存储this对象?

java performance readability memory-consumption

30
推荐指数
2
解决办法
7215
查看次数