我可以成功地做这样的事情,
numbers=[1,2,3]
words=["mum", "cat"]
rule all:
input:
expand("{n}_{w}.txt", n=numbers, w=words)
rule sim:
output:
"{n}_{w}.txt"
shell:
"echo 'Using {wildcards.n} and {wildcards.w}....' && touch {wildcards.n}_{wildcards.w}.txt"
这将按预期创建 6 个文件。
现在我需要将其扩展到更复杂的用例:数字和单词列表是根据先前的规则从保存在 .csv 文件中的数据帧生成的。然后我想使用所述参数值(所有组合)通过papermill以参数化方式执行jupyter笔记本。
数据框对于每个可能重复的参数有一列,所以我会使用这个函数
我认为它会具有像这个函数这样的结构来获取与以前相同的文件列表
def get_values(infile):
data = pd.read_csv(infile)
return list(data.numbers.unique()), list(data.words.unique())
那么 Snakefile 可能具有以下结构,
rule all:
input:
expand("{n}_{w}.txt", n=numbers, w=words)
rule make_csv:
output: dataframe="dataframe.csv"
# not important how it is generated
# Here or in the next rule I am missing how to load the parameter values n and w
rule run_parametrized:
input:
notebook = "my_notebook.ipynb"
(? parameters = rules.make_csv.output.dataframe)
output:
notebook = "result_{n}_{w}.ipynb"
shell:
"papermill {input.notebook} {output.notebook} -p number={n} -p word={w}"
请注意,此处的“全部”目标规则无法工作,因为我事先不知道“数字”和“单词”,因为它们应该由打开 CSV 文件并全局定义这些列表的规则输出。
这需要 Snakemake 的 checkpoint 规则定义。检查点告诉snakemake在执行后重新评估DAG,从而允许数据依赖的条件执行。对于您的示例,您可以执行以下操作:
rule all:
input:
aggregate_ipynbs
def aggregate_ipynbs(wildcards):
checkpoint_output = checkpoints.make_csv.get(**wildcards).output[0] # tell snakemake to wait for checkpoint output
data = pd.read_csv(checkpoint_output)
ns, ws = list(data.numbers.unique()), list(data.words.unique())
return expand("result_{n}_{w}.ipynb", n=ns, w=ws)
checkpoint make_csv:
output: dataframe="dataframe.csv"
# not important how it is generated
# Here or in the next rule I am missing how to load the parameter values n and w
rule run_parametrized:
input:
notebook = "my_notebook.ipynb"
output:
notebook = "result_{n}_{w}.ipynb"
shell:
"papermill {input.notebook} {output.notebook} -p number={n} -p word={w}"