У меня есть конвейер змеи, где мне нужно сделать небольшой шаг обработки данных (применив скользящее среднее значение к кадру данных).
Я хотел бы написать что-то вроде этого:
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}")
"""
Однако это не работает.
Должен ли я создавать файл Python с этими 4 строками кода? Альтернатива, которая приходит мне в голову, немного громоздка. Это было бы
Среднее_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)
А затем правило змеетворения выглядит так:
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}
"""
Есть ли более умный или более эффективный способ сделать это? Это было бы прекрасно! Ждем ваших отзывов!
Этого можно добиться с помощью директивы 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 доступны напрямую через input, output, params и т. д.
Большое спасибо, это то, что я искал! Что вы имеете в виду под прямой доступностью? Или в чем разница между input.df_raw и {input.df_raw}?
Синтаксис фигурных скобок используется при замене значений в директиве shell, но в директиве run вы можете напрямую вызывать соответствующий объект/шаблон. Таким образом, в run вы бы назвали input.df_raw, а не "{input.df_raw}" (который будет использоваться в shell).
Я понимаю. Итак, в вашем ответе params.window также будет без {}, верно? Спасибо!
Вы правы, я исправил код.
Директива run кажется подходящей. Возможно, полезно знать, что вы можете сделать то же самое, используя аргумент -c в python для запуска скрипта, переданного в виде строки. Например.:
shell:
r"""
python -c '
import pandas as pd
df=pd.read_csv("{input.df_raw}")
etc etc...
'
"""
Используйте run: вместо shell: см.: snakemake.readthedocs.io/en/stable/snakefiles/…