def df_elementwise(df, df_other, idCol, op, *cols, renameOutput=False):
    """Join two dataframes with the same schema by id,
    and perform an elementwise operation on the selected columns

    :param df: first dataframe to use
    :type df: pyspark.sql.DataFrame
    :param df_other: second dataframe to use
    :type df_other: pyspark.sql.DataFrame
    :param idCol: column containing the matching ids
    :type idCol: str
    :param op: operation to perform
    :type op: str {"+", "-", "*", "/"}
    :param *cols: columns to perform the operation on
    :type *cols: str
    :param renameOutput: if True, add the opeartion performed to the resulting columns' names, defaults to False
    :type renameOutput: bool, optional
    :returns: resulting dataframe
    :rtype: pyspark.sql.DataFrame
    """

    opStr = {"+": "sum", "-": "dif", "*": "mul", "/": "div"}

    renameCols = [f"`{col}` as `{col}_other`" for col in cols]
    df_j = df.join(df_other.selectExpr(idCol, *renameCols), idCol, "inner")

    if renameOutput:
        opCols = [f"`{col}` {op} `{col}_other` as `{opStr[op]}({col})`"
                  for col in cols]
    else:
        opCols = [f"`{col}` {op} `{col}_other` as `{col}`"
                  for col in cols]
    return df_j.selectExpr(idCol, *opCols)