Python应用小坑备忘录

总结了一些常见的Python用法的小坑,以下Python用法信息适用于Python 2.7.13版本。

最近更新时间:2018-01-17


 

1. 使用int()转换为整数型时,会做向下取整。例如int(38.8)会得到38,而不是39

2. 在使用input()和raw_input接收用户输入时,注意前者获得是一个合法的Python表达式,而后者获得的是一个任何字符串。例如input()输入12会得到一个数值,输入3+1会得到4,而输入abcde则会报错,除非abcde是一个变量或常量对象,因为这不是一个合法表达式,如果要输入字符串需要使用'abcde'。而在raw_input中所有被输入的对象都会被转换为字符串,例如还是上面输入,结果会分别得到'12'、'3+1'、'abcde'。

3. =是赋值符号,==是等值判断符合,二者可能用错,尤其在条件判断中会手下笔误的使用=做判断

4. 区别/和%的作用,前者用于取除数的整数,后者用于取余数。例如5/2=2,而5%2=1。/的结果跟分子或分母的类型有关,例如5./2=2.5(而不是2)。

5. continue和break都有类似于“终止”当前程序执行的意思,但前者用于跳过当次的迭代直接进入下一次,而break则直接终止所有迭代,跳到循环外的语句继续执行。

6. 记得对太长的字符串或公式使用换行符。根据PEP 8规范,每行最大长度79,换行可以使用反斜杠,最好使用圆括号,换行点要在操作符的后边敲回车。

7. 使用print输出浮点数并转换为整数时,如果使用d做格式化,那么会“直接截取”整数部分,如果使用f保留0位小数,则会四舍五入。例如n=12.556, print ('The number is: %.0f' % n)的结果是The number is: 13。而print ('The number is: %d' % n)的结果是12。这点跟int()比较类似。

8. 文件目录中尽量使用/而不是\,例如c:/test/a.txt而不是c:\\test\\a.txt,虽然两个语法的结果是相同的,但前者明显更简洁。(当然,更不能用c:\test\a.txt,这是错误的)

9. 使用Python默认的文件读取方法时,记得在最后使用close()将其关闭掉,否则在多个应用都调取该文件或做操作时会由于冲突而报错。另外一个比较好的办法是使用with open() as f这种方法直接读写文件,这样就不用“手动”文件了,它会在该程序执行完之后自动关闭。

10. 文件读取模式的+模式很好用,例如a+,w+等,尤其在测试时无需关注是否有存在文件可以直接做文件写入。但是在生产应用时,注意先清空里面的测试内容。

11. 使用pandas.read_csv指定分隔符时,如果分隔符不是一个符号,例如多列之间通过“|+|”(没错,是三个符号)分隔的,那么分隔符sep的值为"\|\+\|",这是python正则表达式语法。

12. 在使用pandas做数据切分时,使用columns可以直接选择目标列的数据,但下面2种选择后的结果是不同的。例如:

  1. data_pd = pd.DataFrame(np.arange(12).reshape(3,4),columns=['1','2','3','4'])
  2. pd1 = data_pd[['1']]
  3. pd2= data_pd['1']

使用print方法打印后的结果分别如下:

  1. print (pd1)
  2.    1
  3. 0  0
  4. 1  4
  5. 2  8
  6. print (pd2)
  7. 0    0
  8. 1    4
  9. 2    8
  10. Name: 1, dtype: int32

二者看似结果相同,但实际上是不同类型(tyoe)的对象,前者是一个DataFrame,后者是一个Series。这会影响后后续对于该对象的处理,DataFrame和Series也包含了不同的方法。例如:

    • columns值:pd1是有columns方法的,能获取到值为'1'(列名);而pd2是没有columns方法的。
    • 遍历:如果使用for方法遍历pd1,那么只能得到pd1的列名('1');而遍历pd2时,可以得到每个值。当然,如果你愿意,你仍然可以通过pd1.values.tolist()方法获取到pd1中的值,pd2也是如此,但前者获得的是一个嵌套列表的列表[[0], [4], [8]];后者是一个字符串组合的列表[0, 4, 8]。

13. 通常,当数据中包含NaN(空值)时,在做筛选时是无法使用is nan或==nan判断出来的。原因是NaN代表的是一个非浮点数(比如无理数),并不是一个具体数值。例如,使用np.NaN == np.NaN会得到False,而不是True,这跟Python中其他对象跟自身做判断是截然不同的。要判断特定对象中是否包含NaN值或是否是NaN,可以使用np.isnan做判断。方法是:

  1. strs1 = np.nan
  2. print(np.isnan(strs1))
  3. >>True
  4. strs2 = 12
  5. print(np.isnan(strs2))
  6. >>False

但是,当对象的类型是非数值型时,例如字符串,那么会报错TypeError。例如:

  1. strs3 = 'ab'
  2. print(np.isnan(strs3))
  3. >>...TypeError: ufunc 'isnan' not supported for the input typesand the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

此时,可以配置try except来解决该问题,即在try中通过np.isnan(object)判断,如果得到true执行缺失值处理方法;如果得到false进行数值型处理方法;如果报错,则执行其他处理方法,具体处理方法要根据实际对象的类型而定。

  1. try:  # 如果为空
  2.     np.isnan(strs3)
  3.     #执行特定方法
  4. except TypeError:  # 如果不为空,会报错
  5.     #执行特定方法

 

14. 在使用sklearn的GridSearchCV做超参数优化时,可能会报错sklearn.externals.joblib.my_exceptions.JoblibValueError错误,出现这种错误通常由于存在版本问、参数配置或代码层面有问题,但只通过这个错误信息是无法找到根源的,解决方案通常有三种:

  • 使用from sklearn.model_selection import GridSearchCV来代替from sklearn.grid_search import GridSearchCV来使用最新的库引用
  • 使用pip install -U scikit-learnconda install scikit-learn更新sklearn到最近版本
  • 将GridSearchCV中的n_jobs值设置为1,然后再次运行,此时会出现真正导致错误的原因的错误提示,找到原因并修复;然后再次设置n_jobs=-1,此时就可以正常运行。

====================【好书推荐,我为自己代言】====================

《电商流量数据化运营》出版了!

  • 10余年业务经验总结:将我在甲方和乙方,跨企业和跨行业的经验总结起来,供大家快速提升,少走弯路。
  • 流量运营教科书:内容围绕流量数据化运营的全流程展开,涵盖渠道策略与计划管理、媒体投放与执行管理、渠道投放效果评估与分析、流量运营监控与效果复盘等各个环节。
  • 有用、实用:不讲数据分析理论,不讲数据分析工具使用,所有方法均可在工作中直接使用,而且围绕流量数据化运营的常见问题展开。
  • 易用、易读:不要求会Python,会用Excel就行,无晦涩难懂的理论和复杂的推导过程。
  • 以场景应用为核心:以业务场景为切入点,内容上围绕业务问题、数据支持方案、实用工具实操的思路,用数据解决每个具体业务问题。
如果你对本书感兴趣,请点击这里查看更多信息!当然,你也可以先加我微信了解一下。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注