eshangj/stackoverflow_q_and_a_sample huggingface dataset:
Question: I’m working on a project in Scala and Apache Spark where I need to convert coordinates from Easting/Northing (EPSG:27700) to Latitude/Longitude (EPSG:4326). I have a Python script that uses in built libraries pyproj (transformer) to handle this, but I haven’t found an equivalent way to do it in Scala/Spark. Here’s the Python code I’m currently using:  from pyproj import Transformer import pandas as pd data = { 'node_id': ['94489', '94555', '94806', '99118', '76202'], 'easting': [276164, 428790, 357501, 439545, 357353], 'northing': [84185, 92790, 173246, 336877, 170708] } df = pd.DataFrame(data) transformer = Transformer.from_crs("epsg:27700", "epsg:4326") lat, lon = transformer.transform(df['easting'].values, df['northing'].values) df['longitude'] = lon df['latitude'] = lat print(df)  The output DataFrame should looks like this:    node_id easting northing longitude latitude     94489 276164 84185 -3.752811 50.644154   94555 428790 92790 -1.593413 50.734016   94806 357501 173246 -2.613059 51.456587   99118 439545 336877 -1.413188 52.927852   76202 357353 170708 -2.614883 51.433757   

Answer: @MartinHH Thanks for providing the reference. Looks like it is possible to create same code in scala/spark package com.test.job.function_testing import org.apache.spark.sql.SparkSession import geotrellis.proj4.CRS import geotrellis.proj4.Transform object TestCode { def main(args: Array[String]) = { val runLocally = true val jobName = "Test Spark Logging Case" implicit val spark: SparkSession = Some(SparkSession.builder.appName(jobName)) .map(sparkSessionBuilder => if (runLocally) sparkSessionBuilder.master("local[2]") else sparkSessionBuilder ) .map(_.getOrCreate()) .get import spark.implicits._ val columns = Seq("node_id", "easting", "northing") val data = Seq( (94489, 276164, 84185), (94555, 428790, 92790), (94806, 357501, 173246), (99118, 439545, 336877), (76202, 357353, 170708)) val df = data.toDF(columns: _*) val eastingNorthing = CRS.fromEpsgCode(27700) val latLong = CRS.fromEpsgCode(4326) val transform = Transform(eastingNorthing, latLong) import org.apache.spark.sql.functions._ def transformlatlong = udf((easting: Int, northing: Int) => { val (long, lat) = transform(easting, northing) (long,lat) } ) val newdf = df.withColumn("latlong",transformlatlong(df("easting"),df("northing"))) newdf.select(col("node_id"),col("easting"),col("northing"),col("latlong._1").as("longitude"),col("latlong._2").as("latitude")).show() } }  And here is the output dataframe +-------+-------+--------+-------------------+------------------+ |node_id|easting|northing| longitude| latitude| +-------+-------+--------+-------------------+------------------+ | 94489| 276164| 84185| -3.752810925839862|50.644154475886154| | 94555| 428790| 92790|-1.5934125598396651| 50.73401609723385| | 94806| 357501| 173246|-2.6130593045676984| 51.45658738605824| | 99118| 439545| 336877| -1.413187622652739| 52.92785156624134| | 76202| 357353| 170708| -2.614882589162872| 51.43375699275326| +-------+-------+--------+-------------------+------------------+  And added below library to the build.sbt libraryDependencies += "org.locationtech.geotrellis" %% "geotrellis-raster" % "3.5.2"
Question: I'm using uv workspace with a structure that looks like the following example from the doc. albatross ├── packages │ ├── bird-feeder │ │ ├── pyproject.toml │ │ └── src │ │ └── bird_feeder │ │ ├── __init__.py │ │ └── foo.py │ └── seeds │ ├── pyproject.toml │ └── src │ └── seeds │ ├── __init__.py │ └── bar.py ├── pyproject.toml ├── README.md ├── uv.lock └── src └── albatross └── main.py  How do I tell pytest to use the configuration in each package pyproject.toml while running pytest from the root package(albatross in this case) directory?

Answer: You can tell pytest the directory: uv run pytest packages/bird-feeder  uv run --package bird-feeder doesn't work:  uv run --package bird-feeder pytest doesn't pass pyproject.toml info to pytest. pytest merely infers dir=pathlib.Path.cwd().  uv run --directory packages/bird-feeder works: uv run --directory packages/bird-feeder pytest  Related: Using uv run as a task runner #5903 may be supported in future.
Question: I am trying to update specific rows in a python-polars DataFrame where two columns ("Season" and "Wk") meet certain conditions, using values from a list or Series that should align with the filtered rows. In pandas, I would use .loc[] to do this, but I haven't found a way to achieve the same result with Polars. import polars as pl # Sample DataFrame df = pl.DataFrame({ "Season": [2024, 2024, 2024, 2024], "Wk": [28, 28, 29, 29], "position": [1, 2, 3, 4] }) # List of new values for the filtered rows new_positions = [10, 20] # Example values aligned with the filtered rows # Condition to update only where Season is 2024 and Wk is 29 df = df.with_columns( # Expected update logic here )  I've tried approaches with when().then() and zip_with(), but they either don't accept lists/Series directly or don't align the new values correctly with the filtered rows. Is there a recommended way to update a column conditionally in python-polars with values from a list or Series in the same order as the filter?

Answer: You could generate the indices with when/then and .cum_sum() df.with_columns( idx = pl.when(Season=2024, Wk=29).then(1).cum_sum() - 1 )  shape: (4, 4) ┌────────┬─────┬──────────┬──────┐ │ Season ┆ Wk ┆ position ┆ idx │ │ --- ┆ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 ┆ i32 │ ╞════════╪═════╪══════════╪══════╡ │ 2024 ┆ 28 ┆ 1 ┆ null │ │ 2024 ┆ 28 ┆ 2 ┆ null │ │ 2024 ┆ 29 ┆ 3 ┆ 0 │ │ 2024 ┆ 29 ┆ 4 ┆ 1 │ └────────┴─────┴──────────┴──────┘  Which you can .get() and then .fill_null() the remaining original values. df.with_columns( pl.lit(pl.Series(new_positions)) .get(pl.when(Season=2024, Wk=29).then(1).cum_sum() - 1) .fill_null(pl.col.position) .alias("position") )  shape: (4, 3) ┌────────┬─────┬──────────┐ │ Season ┆ Wk ┆ position │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞════════╪═════╪══════════╡ │ 2024 ┆ 28 ┆ 1 │ │ 2024 ┆ 28 ┆ 2 │ │ 2024 ┆ 29 ┆ 10 │ │ 2024 ┆ 29 ┆ 20 │ └────────┴─────┴──────────┘  Or perhaps .replace_strict() df.with_columns( (pl.when(Season=2024, Wk=29).then(1).cum_sum() - 1) .replace_strict(dict(enumerate(new_positions)), default=pl.col.position) .alias("position") )
Question: I have a pandas dataframe where a value sometimes gets NA. I want to fill this column with a list of strings with the same length as another column: import pandas as pd import numpy as np df = pd.DataFrame({"a": ["one", "two"], "b": ["three", "four"], "c": [[1, 2], [3, 4]], "d": [[5, 6], np.nan]})     a b c d     one three [1, 2] [5, 6]   two four [3, 4] NaN    and I want this to become    a b c d     one three [1, 2] [5, 6]   two four [3, 4] [no_value, no_value]    I tried df["d"] = np.where(df.d.isna(), ['no_value' for element in df.c], df.d)  and df["d"] = np.where(df.d.isna(), ['no_value'] * len(df.c), df.d)  but both does not work. Anyone has an idea? SOLUTION: I adjusted PaulS answer a little to: df[‘d‘] = np.where(df.d.isna(), pd.Series([['no_value'] * len(lst) for lst in df.c]), df.d)) 

Answer: A possible solution consists in using np.where. df.assign(d = np.where( df['d'].isna(), pd.Series([['no_value'] * len(lst) for lst in df['c']]), df['d']))   Another possible solution, which uses:  apply on df, iterating through each row with a lambda function that checks whether the value in column d is NaN.  If the condition is met, the function generates a new list filled with the string 'no_value' repeated to match the length of the list in column c.  If x['d'] does not meet these conditions, the original value in x['d'] is retained.   df['d'] = df.apply( lambda x: ['no_value'] * len(x['c']) if (x['d'] is np.nan) else x['d'], axis=1)   Output:  a b c d 0 one three [1, 2] [5, 6] 1 two four [3, 4] [no_value, no_value]
Question: I need to divide an audio file to have chunks that are less than 25mb. I would like to not have to save the file on the disk. This is the code I have for now, but it is not working as expected, as it splits the audio in chunks of around 2mb def audio_splitter(audio_file) audio = AudioSegment.from_file(audio_file) # Set the chunk size and overlap target_chunk_size = 20 * 1024 * 1024 # Target chunk size in bytes (20 MB) # Overlap in milliseconds (10 seconds) overlap_duration = 10 * 1000 # Estimate the number of bytes per millisecond in the audio bytes_per_ms = len(audio.raw_data) / len(audio) # Calculate duration of each chunk in milliseconds chunk_duration = int(target_chunk_size / bytes_per_ms) chunks = [] start = 0 while start < len(audio): end = start + chunk_duration chunk = audio[start:end] chunks.append(chunk) start += chunk_duration - overlap_duration for i, chunk in enumerate(chunks): chunk.export(f"chunk_{i + 1}.mp3", format="mp3")  I think there is a problem with len(audio.raw_data) as it seems not to return the correct byte size. Is there a better method altogheter to approach this problem?

Answer: You can use bytes.IO estimation In my test case I used 1/2 mb limit and files were all exactly 512kb,512kb,426kb,71.1kb from pydub import AudioSegment import io import sys import os def audio_splitter(audio_file): audio = AudioSegment.from_file(audio_file) test = audio[0:len(audio)] test_io = io.BytesIO() test.export(test_io, format="mp3") test_size = sys.getsizeof(test_io) # Set the chunk size and overlap target_chunk_size = 20 * 1024 * 1024 # Target chunk size in bytes (20 MB) # Overlap in milliseconds (10 seconds) overlap_duration = 10 * 1000 # Estimate the number of bytes per millisecond in the audio bytes_per_ms = test_size/len(audio) # Estimation # Calculate duration of each chunk in milliseconds chunk_duration = int(target_chunk_size / bytes_per_ms) chunks = [] start = 0 while start < len(audio): end = start + chunk_duration chunk = audio[start:end] chunks.append(chunk) start += chunk_duration - overlap_duration for i, chunk in enumerate(chunks): chunk.export(f"chunk_{i + 1}.mp3", format="mp3") if __name__ == "__main__": audio_splitter(*sys.argv[1:])   in bytes_per_ms I am doing average, you can even do this for every chunk but it will cost you memory,so it depends on your accuracy vs speed criteria, mine is almost accurate for realtime audio(everywhere same byte distribution on average) and fast.
Question: I have a server program (let's call it my-server) I cannot alter and I am interested in measuring its maximum memory usage from when it starts to when a certain external event occurs. I am able to do it manually on my shell by:  running /usr/bin/time -f "%M" my-server  triggering the external event  sending an INT signal to the process by pressing CTRL + C  reading the standard error   I'd like to do this programmatically using Python. If not possible I'd like to find an alternative simple way to achieve the same result. I tried launching the same command as a subprocess and sending an INT signal to it: import signal import subprocess proc = subprocess.Popen( ["/usr/bin/time", "-f", "%M", "my-server"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True ) # ...wait for external event proc.send_signal(signal.SIGINT) out, err = proc.communicate() # both out and err are ""  however both out and err are empty. The same script works fine for processes that terminate: proc = subprocess.Popen( ["/usr/bin/time", "-f", "%M", "echo", "hello"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True ) out, err = proc.communicate() # out is "hello", err is "1920"  but for processes that need to be terminated via signal I am not sure how to retrieve stderr after termination was issued. (or even before it, despite not useful) The following somewhat equivalent example may be useful for testing: terminate-me.py import signal import sys def signal_handler(sig, frame): print('Terminated', file=sys.stderr) # Need to read this sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print('Send SIGINT to terminate') signal.pause()  main.py import signal import subprocess proc = subprocess.Popen( ["python", "terminate-me.py"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True ) # No need to wait for any external event proc.send_signal(signal.SIGINT) out, err = proc.communicate() print(out) print(err) 

Answer: It turns out I misunderstood /usr/bin/time's behavior. I thought that when receiving an INT signal time would relay it to its sub-process being measured, waited for it to terminate, and then terminated normally outputting its results. What happens instead is that time simply terminates before outputting any result. When executing within a shell, pressing CTRL + C actually sends an INT signal to both, but the sub-process terminates before time does, so time is able to complete its execution and it appears as if time awaited the sub-process. Therefore in my script I was able to make it work by only sending the INT signal to the sub-process: (actually, to all of its sub-processes for simplicity) import signal import subprocess import psutil proc = subprocess.Popen( ["/usr/bin/time", "-f", "%M", "my-server"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, text=True ) # Wait for external event... children = psutil.Process(proc.pid).children() for child in children: child.send_signal(signal.SIGINT) out, err = proc.communicate()
Question: In the past, I install my personal package with setup.py: python setup.py install  Now this method is deprecated, and I can only use pip: python -m pip install .  However, the method with setup.py can show install messages, but pip method cannot. For example, when there is c++ code which requires compiling the source code, the setup.pymethod can print warnings to the screen, but thepip` method only let you wait until everything is done. Is there any method that I can see more messages with pip like the setup.py in the past?

Answer: You can force pip to be more verbose using pip -v install. The option is additive, and can be used up to 3 times to increase verbosity: pip -v install pip -vv install pip -vvv install
Question: I have a dataframe: df = pd.DataFrame({"ID": ["ID1", "ID2", "ID3", "ID4", "ID5"], "Item": ["Item1", "Item2", "Item3", "Item4","Item5"], "Catalog1": ["cat1", "1Cat12", "Cat35", "1cat3","Cat5"], "Catalog2": ["Cat11", "Cat12", "Cat35", "1Cat1","2cat5"], "Catalog3": ["cat6", "Ccat2", "1Cat9", "1cat3","Cat7"], "Price": ["716", "599", "4400", "150","139"]})  I need to find all rows, that contain string "cat1" or "Cat1" in any column with name starting with Catalog (the number of these columns may vary, so I can't just list them). I tried: filter_col = [col for col in df if col.startswith('Catalog')] df_res = df.loc[(filter_col.str.contains('(?i)cat1'))]  But I get mistake: AttributeError: 'list' object has no attribute 'str'

Answer: In your code, filter_col is a list. You can't use str with it. You can make use of pandas functions to do the operations faster. Here's the code to solve it: import pandas as pd # Create the DataFrame df = pd.DataFrame({"ID": ["ID1", "ID2", "ID3", "ID4", "ID5"], "Item": ["Item1", "Item2", "Item3", "Item4","Item5"], "Catalog1": ["cat1", "1Cat12", "Cat35", "1cat3","Cat5"], "Catalog2": ["Cat11", "Cat12", "Cat35", "1Cat1","2cat5"], "Catalog3": ["cat6", "Ccat2", "1Cat9", "1cat3","Cat7"], "Price": ["716", "599", "4400", "150","139"]}) # Define the search strings search_strings = ["cat1", "Cat1"] # Filter the DataFrame filtered_df = df[df.filter(like='Catalog').apply(lambda row: row.str.contains('|'.join(search_strings), case=False).any(), axis=1)] print(filtered_df)
Question: Why the following code does not return [1,4,3,4]? Hasn't a already changed during the reversed order assignment? a=np.array([1,2,3,4]) a[1::]=a[:0:-1]  The result is: array([1, 4, 3, 2]) 

Answer: You're right that a changes during the assignment, which in turn affects the view whose elements you're assigning into a. If NumPy didn't have special handling for this case, you could indeed see array([1, 4, 3, 4]) as a result. However, NumPy checks for this case. If NumPy detects that the RHS of the assignment may share memory with the array being assigned to, it makes a copy of the RHS first, to avoid this kind of problem: if (tmp_arr && solve_may_share_memory(self, tmp_arr, 1) != 0) { Py_SETREF(tmp_arr, (PyArrayObject *)PyArray_NewCopy(tmp_arr, NPY_ANYORDER)); }
Question: I'm working with a pyspark dataframe (in Python) containing time series data. Data got a structure like this: event_time variable value step ID 1456942945 var_a 123.4 1 id_1 1456931076 var_b 857.01 1 id_1 1456932268 var_b 871.74 1 id_1 1456940055 var_b 992.3 2 id_1 1456932781 var_c 861.3 2 id_1 1456937186 var_c 959.6 3 id_1 1456934746 var_d 0.12 4 id_1 1456942945 var_a 123.4 1 id_2 1456931076 var_b 847.01 1 id_2 1456932268 var_b 871.74 1 id_2 1456940055 var_b 932.3 2 id_2 1456932781 var_c 821.3 3 id_2 1456937186 var_c 969.6 4 id_2 1456934746 var_d 0.12 4 id_2  For each id i got each variable's value at a specific "step". I need to subset this dataframe like this: for each id take all the rows corresponding to steps 1, 2, 3 and a portion of step 4 data starting from the first_event time value of step 4, let's say first 25%. This portioning is to be done with respect to event time. I'm able to do it for a single id, after having subset the DF based on that id: # single step partitioning threshold_value = DF.selectExpr(f"percentile_approx({"event_time"}, {0.25}) as threshold").collect()[0]["threshold"] partitioned_df= DF.filter(col(column_name) <= threshold_value) # First 3 steps first_3_steps_df = DF.filter((col("step").isin([1,2,3])))  And then i would concat the partitioned_df and first_3_steps_df to obtain the desidered output for 1 specific id. I'm stuck at iterating this kind of partitioning for each id in DF without actually iterating that process for each id separately. I'm also able to do it in pandas, but the DF is huge and i really need to stick to Pyspark, so no Pandas answers, please.

Answer: Group the data by ID and use percentile_approx as aggregation function to calculate the threshold for step=4. Then create a where clause with these values to filter the data: from pyspark.sql import functions as F df = ... threshold = df.where('step = 4') \ .groupBy('ID') \ .agg(F.percentile_approx('event_time', 0.25)) \ .collect() threshold = [(r[0],r[1]) for r in threshold] whereStmt = 'step=1 or step=2 or step=3' for r in threshold: whereStmt = whereStmt + f' or (step=4 and ID={r[0]} and event_time<={r[1]})' df.where(F.expr(whereStmt)).show()
Question: Consider the following pl.DataFrame: import polars as pl data = { "symbol": ["AAPL"] * 5 + ["GOOGL"] * 3 + ["MSFT"] * 4, "date": [ "2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04", "2023-01-05", # AAPL has 5 dates "2023-01-01", "2023-01-02", "2023-01-03", # GOOGL has 3 dates "2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04", # MSFT has 4 dates ], } df = pl.DataFrame(data) with pl.Config(tbl_rows=-1): print(df) shape: (12, 2) ┌────────┬────────────┐ │ symbol ┆ date │ │ --- ┆ --- │ │ str ┆ str │ ╞════════╪════════════╡ │ AAPL ┆ 2023-01-01 │ │ AAPL ┆ 2023-01-02 │ │ AAPL ┆ 2023-01-03 │ │ AAPL ┆ 2023-01-04 │ │ AAPL ┆ 2023-01-05 │ │ GOOGL ┆ 2023-01-01 │ │ GOOGL ┆ 2023-01-02 │ │ GOOGL ┆ 2023-01-03 │ │ MSFT ┆ 2023-01-01 │ │ MSFT ┆ 2023-01-02 │ │ MSFT ┆ 2023-01-03 │ │ MSFT ┆ 2023-01-04 │ └────────┴────────────┘  I need to make each group's dates (grouped_by symbol) consistent accross all groups. Therefore, I need to identify the common dates across all groups (probably using join) and subsequently filter the dataframe accordingly. It might be related to Find intersection of columns from different polars dataframes. I am looking for a generalized solution. In the above example the resulting pl.DataFrame should look as follows: shape: (9, 2) ┌────────┬────────────┐ │ symbol ┆ date │ │ --- ┆ --- │ │ str ┆ str │ ╞════════╪════════════╡ │ AAPL ┆ 2023-01-01 │ │ AAPL ┆ 2023-01-02 │ │ AAPL ┆ 2023-01-03 │ │ GOOGL ┆ 2023-01-01 │ │ GOOGL ┆ 2023-01-02 │ │ GOOGL ┆ 2023-01-03 │ │ MSFT ┆ 2023-01-01 │ │ MSFT ┆ 2023-01-02 │ │ MSFT ┆ 2023-01-03 │ └────────┴────────────┘ 

Answer: You could count the number of unique (n_unique) symbols over date and filter the rows that have all symbols: df.filter(pl.col('symbol').n_unique().over('date') .eq(pl.col('symbol').n_unique()))  Output: ┌────────┬────────────┐ │ symbol ┆ date │ │ --- ┆ --- │ │ str ┆ str │ ╞════════╪════════════╡ │ AAPL ┆ 2023-01-01 │ │ AAPL ┆ 2023-01-02 │ │ AAPL ┆ 2023-01-03 │ │ GOOGL ┆ 2023-01-01 │ │ GOOGL ┆ 2023-01-02 │ │ GOOGL ┆ 2023-01-03 │ │ MSFT ┆ 2023-01-01 │ │ MSFT ┆ 2023-01-02 │ │ MSFT ┆ 2023-01-03 │ └────────┴────────────┘  Intermediates: ┌────────┬────────────┬───────────────────┬───────────────────┐ │ symbol ┆ date ┆ nunique_over_date ┆ eq_symbol_nunique │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ u32 ┆ bool │ ╞════════╪════════════╪═══════════════════╪═══════════════════╡ │ AAPL ┆ 2023-01-01 ┆ 3 ┆ true │ │ AAPL ┆ 2023-01-02 ┆ 3 ┆ true │ │ AAPL ┆ 2023-01-03 ┆ 3 ┆ true │ │ AAPL ┆ 2023-01-04 ┆ 2 ┆ false │ │ AAPL ┆ 2023-01-05 ┆ 1 ┆ false │ │ GOOGL ┆ 2023-01-01 ┆ 3 ┆ true │ │ GOOGL ┆ 2023-01-02 ┆ 3 ┆ true │ │ GOOGL ┆ 2023-01-03 ┆ 3 ┆ true │ │ MSFT ┆ 2023-01-01 ┆ 3 ┆ true │ │ MSFT ┆ 2023-01-02 ┆ 3 ┆ true │ │ MSFT ┆ 2023-01-03 ┆ 3 ┆ true │ │ MSFT ┆ 2023-01-04 ┆ 2 ┆ false │ └────────┴────────────┴───────────────────┴───────────────────┘
Question: I am training a model in pytorch and would like to be able to programmatically change some components of the model architecture to check which works best without any if-blocks in the forward(). Consider a toy example: import torch class Model(torch.nn.Model): def __init__(self, layers: str, d_in: int, d_out: int): super().__init__() self.layers = layers linears = torch.nn.ModuleList([ torch.nn.Linear(d_in, d_out), torch.nn.Linear(d_in, d_out), ]) def forward(x1: torch.Tensor, x2: torch.Tensor) -> torch.Tensor: if self.layers == "parallel": x1 = self.linears[0](x1) x2 = self.linears[1](x2) x = x1 + x2 elif self.layers == "sequential": x = x1 + x2 x = self.linears[0](x) x = self.linears[1](x) return x  My first intution was to provide external functions, e.g. def parallel(x1, x2): x1 = self.linears[0](x1) x2 = self.linears[1](x2) return x1 + x2  and provide them to the model, like class Model(torch.nn.Model): def __init__(self, layers: str, d_in: int, d_out: int, fn: Callable): super().__init__() self.layers = layers linears = torch.nn.ModuleList([ torch.nn.Linear(d_in, d_out), torch.nn.Linear(d_in, d_out), ]) self.fn = fn def forward(x1: torch.Tensor, x2: torch.Tensor) -> torch.Tensor: x = self.fn(x1, x2)  but of course the function's scope does not know self.linears and I would also like to avoid having to pass each and every architectural element to the function. Do I wish for too much? Do I have to "bite the sour apple" as it says in German and either have larger function signatures, or use if-conditions, or something else? Or is there a solution to my problem?

Answer: You could just use the if statement in the init function or in another function, for example: from enum import Enum class ModelType(Enum): Parallel = 1 Sequential = 2 class Model(torch.nn.Model): def __init__(self, layers: str, d_in: int, d_out: int, model_type: ModelType): super().__init__() self.layers = layers linears = torch.nn.ModuleList([ torch.nn.Linear(d_in, d_out), torch.nn.Linear(d_in, d_out), ]) self.model_type = model_type self.initialize() def initialize(self): if self.model_type == ModelType.Parallel: self.fn = self.parallel else if self.model_type == ModelType.Sequential:: self.fn = self.sequential def forward(self, x1: torch.Tensor, x2: torch.Tensor) -> torch.Tensor: x = self.fn(x1, x2) return x def parallel(self, x1, x2): x1 = self.linears[0](x1) x2 = self.linears[0](x2) x = x1 + x2 return x def sequential(self, x1, x2): x = x1 + x2 x = self.linears[0](x) x = self.linears[0](x) return x  I hope it helps.