直接在 Snakemake 上运行短小的 Python 代码。

3

我有一个snakemake流程,其中我需要对数据进行一个小步骤的处理(对数据帧应用滚动平均)。

我想写出类似这样的代码:

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}")
        """

然而它并不起作用。

我是否需要创建一个包含这4行代码的Python文件?我想到的另一种选择有点繁琐。它将是

average_df.py

import pandas as pd


def average_df(i_path, o_path, window):

        df=pd.read_csv(path)
        df=df.rolling(window=window, center=True, min_periods=1).mean()
        df.to_csv(o_path)

        return None


if __name__ == "__main__":
    import argparse

    parser = argparse.ArgumentParser(description='Description of your program')
    parser.add_argument('-i_path', '--input_path', help='csv file', required=True)
    parser.add_argument('-o_path', '--output_path', help='csv file ', required=True)
    parser.add_argument('-w', '--window', help='window for averaging', required=True)


    args = vars(parser.parse_args())

    i_path = args['input_path']
    o_path = args['output_path']
    window = args['window']

    average_df(i_path, o_path, window)


然后,将snakemake规则设置为以下内容:

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

有没有更聪明或更有效的方法来做这件事?那将是太棒了!期待您的意见!


1
使用 run: 替代 shell: 参见:https://snakemake.readthedocs.io/en/stable/snakefiles/rules.html#snakefiles-and-rules - Alex
2个回答

2

这可以通过run指令实现:

rule average_df:
    input:
        # script = ,
        df_raw = "{sample}_raw.csv"
    params:
        window = 83
    output:
        df_avg = "{sample}_avg.csv"
    run:
        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)

请注意,所有的snakemake对象都可以直接通过inputoutputparams等访问。

1
非常感谢,这正是我在寻找的! 你说的“直接可用”是什么意思? 或者input.df_raw和{input.df_raw}之间有什么区别? - Ulises Rey
1
大括号语法用于在“shell”指令中替换值,但在“run”指令中,您可以直接调用相关的对象/通配符。因此,在“run”中,您将调用input.df_raw而不是"{input.df_raw}"(后者将在“shell”中使用)。 - SultanOrazbayev
1
我明白了。所以在你的回答中,params.window 也应该没有 {},对吗? 谢谢! - Ulises Rey
1
你说得对,我已经修复了代码。 - SultanOrazbayev

1
< p > run 指令似乎是最好的选择。你可能需要知道,你可以使用 python 中的 -c 参数来运行作为字符串传递的脚本。例如:

shell:
        r"""
python -c '
import pandas as pd
df=pd.read_csv("{input.df_raw}")
etc etc...
'
        """ 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接