【问题标题】:Is there a more pythonic way to nest conditional statements for filling a new column in a pandas df?是否有更 Pythonic 的方式来嵌套条件语句以填充 pandas df 中的新列?
【发布时间】:2020-08-24 08:38:33
【问题描述】:

我是 pandas 和 python 的新手,我搜索过但找不到我的问题。我正在尝试根据另一列“NO”的内容,找到在 Pandas 数据框“Sample Location”中填充新列的最佳方法,将它们放入定义的集合中。

第一个问题是:

        if TestLocation == 'LH Duct': 
            df['Sample Location'] = df.apply(
                lambda x: samplePoint(x['NO']),
                axis=1
            )    

我不确定是否正确形成,因为我的数据框有点混乱。

第二个问题 - 有没有更 Pythonic 的方式来做这个检查:

def samplePoint(n):
    if n <= 15:
        v = 'P1 S1'
    elif n >= 20 & n <= 35:
        v = 'P1 S2'
    elif n >= 40 & n <= 55:
        v = 'P1 S3'
    elif n >= 60 & n <= 75:
        v = 'P1 S4'
    elif n >= 80 & n <= 95:
        v = 'P1 S5'
    elif n >= 100 & n <= 115:
        v = 'P1 S6'
    elif n >= 150 & n <= 165:
        v = 'P2 S1'
    elif n >= 170 & n <= 185:
        v = 'P2 S2'
    elif n >= 190 & n <= 205:
        v = 'P2 S3'
    elif n >= 210 & n <= 225:
        v = 'P2 S4'
    elif n >= 230 & n <= 245:
        v = 'P2 S5'
    elif n >= 250 & n <= 265:
        v = 'P2 S6'
    else:
        v = 'null'
    return v

我认为整个事情可以/应该作为一个 apply/lambda 来完成,但我有点迷失了。如果有人能解释这一点或给我一个好的链接,我将永远感激不尽!

【问题讨论】:

  • 看看可能使用字典列表,在其中定义 v 描述符的低值和高值,例如:'score = [{“low”=0, “high”=15, “v ”=“p1 s1”},{“低”=20,“高”=35,“v”=“p1 s2”},]'。现在,当您获得分数 n 时,您可以在列表中查看要选择的 dict。

标签: python pandas dataframe nested-if


【解决方案1】:

可能v_code的值是可以计算出来的,否则我会把选项放在一个dicts列表中,我写函数samplePoint如下:

samples = [
    {'range': (0, 15),
     'v_code': 'P1 S1'},
    {'range': (20, 35),
     'v_code': 'P1 S3'},
    {'range': (60, 75),
     'v_code': 'P1 S4'},
    {'range': (80, 95),
     'v_code': 'P1 S5'},
    {'range': (100, 115),
     'v_code': 'P1 S6'},
    {'range': (150, 165),
     'v_code': 'P2 S1'},
    {'range': (170, 185),
     'v_code': 'P2 S2'},
    {'range': (190, 205),
     'v_code': 'P2 S3'},
    {'range': (210, 225),
     'v_code': 'P2 S4'},
    {'range': (230, 245),
     'v_code': 'P2 S5'},
    {'range': (250, 265),
     'v_code': 'P2 S6'},
]


def samplepoint(n):
    for sample in samples:
        if sample['range'][0] <= n <= sample['range'][1]:
            return sample['v_code']

    return 'null'

if __name__ == '__main__':
    print(samplepoint(10))

还根据 Python 命名约定将 samplePoint 重命名为 samplepoint。为了使模块不那么混乱,您可以从保留所有常量和设置的配置文件中导入列表samples。因此

from my_config import samples

def samplepoint(n):
    for sample in samples:
        if sample['range'][0] <= n <= sample['range'][1]:
            return sample['v_code']

    return 'null'

if __name__ == '__main__':
    print(samplepoint(100))

文件my_config.py在哪里

samples = [
    {'range': (0, 15),
     'v_code': 'P1 S1'},
    {'range': (20, 35),
     'v_code': 'P1 S3'},
    {'range': (60, 75),
     'v_code': 'P1 S4'},
    {'range': (80, 95),
     'v_code': 'P1 S5'},
    {'range': (100, 115),
     'v_code': 'P1 S6'},
    {'range': (150, 165),
     'v_code': 'P2 S1'},
    {'range': (170, 185),
     'v_code': 'P2 S2'},
    {'range': (190, 205),
     'v_code': 'P2 S3'},
    {'range': (210, 225),
     'v_code': 'P2 S4'},
    {'range': (230, 245),
     'v_code': 'P2 S5'},
    {'range': (250, 265),
     'v_code': 'P2 S6'},
]

【讨论】:

  • 谢谢你,Bruno... 我需要如何管理外部 my_config.py 文件?只需将其保存在与 main.py 脚本相同的目录中?或者当你安装像 matplotlib 这样的 python 包时,我是否必须做一些事情?
  • 只要在你的 main.py 目录下写一个名为 my_config.py 的 python 文件。
【解决方案2】:

尝试内置pd.cut 方法,只是假设x 是数据框和NO 列您正在处理的示例:

pd.cut(x['NO'], bins=[15,25,35,40], right=True, labels=False)

根据您的需要调整箱和边缘/对齐方式。

【讨论】:

  • 谢谢@ipj。我将阅读这个内置方法。
【解决方案3】:

试试这样:

elif n >= 20 & n <= 35:

=>

elif 20 <= n <= 35:

【讨论】:

  • 谢谢@Schiz,这更像是pythonic!
猜你喜欢
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 2013-11-18
  • 2013-08-04
  • 1970-01-01
  • 2017-04-04
相关资源
最近更新 更多