Pandas .loc 和 PEP8

Pandas .loc and PEP8

我已经尝试搜索了很多次,但我没有看到它的答案,所以这里...

我经常使用 pandas 来清理数据框并使其符合我的需要。随之而来的是很多 .loc 访问以查询它和 return 值。根据我正在做的事情(和列的长度),这可能会变得相当冗长。鉴于 PEP8 限制每行 79 个字符,是否有任何最佳实践?下面的一些示例(这些已简化并用于解释目的):

missing_address_df = address_df.loc[address_df['address'].notnull()].copy()

或多个查询点:

nc_drive_df = address.loc[(address_df['address'].str.contains('drive')) & (address_df['state'] == 'NC')]

我有两点建议

  • 忽略 PEP 8 的 80 个字符的建议,但尽量保持在 120 或 150 行
    保持 一些 行长度要求有助于提高可读性,但如果您试图在(例如)class 方法中保持 80 个字符,则会导致更糟和 less-readable 代码

    PEP 8 实际上有一个关于此的部分,A Foolish Consistency is the Hobgoblin of Little Minds,它描述了您应该偏离其其他建议的情况,例如

    1. When applying the guideline would make the code less readable, even for someone who is used to reading code that follows this PEP
  • .loc 内容分成多行

    nc_drive_df = address.loc[
        (address_df['address'].str.contains('drive')) & \
        (address_df['state'] == 'NC')
    ]
    

很难 objective 关于什么时候代码“看起来很糟糕”,尽管语法是有效的,但你会体验到它。实际上,PEP 8 和 Cyclomatic Complexity 检查器是帮助您以科学的方式对抗、捍卫和提出代码风格的工具。


如果您有很多布尔语句,您(通常必须)用括号将它们分开以阐明它们的顺序

nc_drive_df = address.loc[
    (
        (address_df['address'].str.contains('drive')) & \
        (address_df['state'] == 'NC')
    ) || (
        address_df['zip'] == "00000"
    )
]

这与传统的 Python 运算符有些冲突,后者是 suggested to preceed lines (PEP8),但我在形成 Pandas 布尔数组时质疑这一点,因为数据帧 必须相同才能获得好的结果,并且在处理许多数据帧时更容易观察到这一点。

最后,经常在做科学的时候Python,如果可能的话,绝对应该针对部分和完整的数据尝试多种可能性,以得出良好的性能结论,将其可读性放在第二位,并提供关于和的优秀评论以任何特定风格链接到您的研究等。