You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Snakemake流程中直接运行简短Python数据处理代码?

解决Snakemake中DataFrame滚动平均的高效实现方式

问题描述

我在Snakemake流程中需要对DataFrame应用滚动平均,尝试直接在rule的shell指令中编写Python代码但无法正常运行:

rule average_df:
    input:
        # script = ,
        df_raw = "{sample}_raw.csv"
    params:
        window = 83
    output:
        df_avg = "{sample}_avg.csv"
    shell:
        """
        python
        import pandas as pd
        df=pd.read_csv("{input.df_raw}")
        df=df.rolling(window={params.window}, center=True, min_periods=1).mean()
        df.to_csv("{output.df_avg}")
        """

不想编写带argparse的繁琐独立脚本,询问是否有更智能高效的实现方式。

高效实现方法

方法1:修复shell指令中的Python调用

原来的shell代码无法运行是因为没有通过-c参数将代码传递给Python解释器,直接换行的代码会被shell当作独立命令执行。修正后无需独立脚本:

rule average_df:
    input:
        df_raw = "{sample}_raw.csv"
    params:
        window = 83
    output:
        df_avg = "{sample}_avg.csv"
    shell:
        """
        python -c "
        import pandas as pd
        df = pd.read_csv('{input.df_raw}')
        df = df.rolling(window={params.window}, center=True, min_periods=1).mean()
        df.to_csv('{output.df_avg}')
        "
        """

注意:如果路径包含空格,需要确保引号正确转义,或者改用单引号包裹路径。

方法2:使用Snakemake内置的script指令(推荐)

Snakemake支持直接在rule中内嵌Python脚本,通过snakemake对象直接访问输入、输出和参数,无需字符串替换,代码更简洁安全:

rule average_df:
    input:
        df_raw = "{sample}_raw.csv"
    params:
        window = 83
    output:
        df_avg = "{sample}_avg.csv"
    script:
        """
        import pandas as pd
        df = pd.read_csv(snakemake.input.df_raw)
        df = df.rolling(window=snakemake.params.window, center=True, min_periods=1).mean()
        df.to_csv(snakemake.output.df_avg)
        """

这种方式完全避免了shell层的引号问题,Snakemake会自动处理脚本的执行环境,是最推荐的方案。

方法3:简化独立脚本(若需复用)

如果确实需要独立脚本,无需使用argparse,用sys.argv直接接收参数即可大幅简化代码:

average_df.py:

import pandas as pd
import sys

def average_df(i_path, o_path, window):
    df = pd.read_csv(i_path)
    # 注意将window转为整数,因为sys.argv传入的是字符串
    df = df.rolling(window=int(window), center=True, min_periods=1).mean()
    df.to_csv(o_path)

if __name__ == "__main__":
    average_df(sys.argv[1], sys.argv[2], sys.argv[3])

对应的Snakemake规则:

rule average_df:
    input:
        df_raw = "{sample}_raw.csv"
    params:
        window = 83
    output:
        df_avg = "{sample}_avg.csv"
    shell:
        "python average_df.py {input.df_raw} {output.df_avg} {params.window}"

内容的提问来源于stack exchange,提问作者Ulises Rey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:35:14