Skip to content

Commit 11c36e9

Browse files
committed
[read_csv] -update chunk function arg logic
1 parent 234d73e commit 11c36e9

3 files changed

Lines changed: 35 additions & 17 deletions

File tree

src/akutils/pandas_read_files.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
)
1313
from akutils.utils_functions import (
1414
timeit,
15-
sanitize_function_args_from_locals,
16-
control_if_usecols_exist_in_df
15+
contruct_function_args_from_locals,
1716
)
1817
from akutils.os import list_files_from_dir, warn
1918

@@ -22,6 +21,7 @@
2221
def read_csv_in_chunks(
2322
filepath_or_buffer: FilePath | ReadCsvBuffer[bytes] | ReadCsvBuffer[str],
2423
chunk_func: Callable | None = None,
24+
chunk_func_kwarg=None,
2525
chunksize: int = 10**6,
2626
dtype: DtypeArg | None = "string",
2727
**kwargs
@@ -62,17 +62,17 @@ def filter_on_countries(df, countries):
6262
chunksize=5
6363
)
6464
"""
65+
if chunk_func_kwarg is None:
66+
chunk_func_kwarg = {}
6567
print(f"File: {filepath_or_buffer}")
6668
locals_args = locals() # get all args passed in the function
67-
read_csv_args = sanitize_function_args_from_locals(pd.read_csv, locals_args)
68-
read_csv_args = control_if_usecols_exist_in_df(**read_csv_args)
69+
read_csv_args = contruct_function_args_from_locals(pd.read_csv, locals_args)
6970

7071
df = pd.DataFrame()
7172
counter = 0
7273
for chunk in pd.read_csv(**read_csv_args):
7374
print(f"Chunk number => {counter}")
74-
chunk_func_kwarg = sanitize_function_args_from_locals(chunk_func, locals_args)
75-
chunk = chunk_func(chunk, **chunk_func_kwarg) if chunk_func else chunk
75+
chunk = chunk_func(df=chunk, **chunk_func_kwarg) if chunk_func else chunk
7676
df = pd.concat([df, chunk], axis=0, ignore_index=True)
7777
counter += 1
7878
return df

src/akutils/tests/unit/test_pandas_read_files.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ def test_read_csv_in_chunk_with_filtered_function(self):
2828
columns=["col1", "col2", "country"]
2929
)
3030

31-
def filter_chunk(df_chunk: pd.DataFrame, countries: list) -> pd.DataFrame:
32-
return df_chunk[df_chunk["country"].isin(countries)]
31+
def filter_chunk(df: pd.DataFrame, countries: list) -> pd.DataFrame:
32+
return df[df["country"].isin(countries)]
3333

3434
file_path = PATH_TO_AKUTILS_PKG / "tests" / "_fixtures" / "sales.csv"
3535
df = ak.read_csv_in_chunks(
3636
file_path,
3737
chunk_func=filter_chunk,
38+
chunk_func_kwarg={"countries": ["Spain"]},
3839
chunksize=5,
39-
countries=["Spain"],
4040
sep=";",
4141
dtype=None
4242
)
@@ -51,21 +51,23 @@ def test_read_csv_in_chunk_with_add_cols_function(self):
5151
df_expected["new_col"] = (df_expected["col1"] + df_expected["col2"]) * 2.4 + 151
5252

5353
def add_new_col_to_chunk(
54-
df_chunk: pd.DataFrame,
54+
df: pd.DataFrame,
5555
factor: float,
5656
constant: int
5757
) -> pd.DataFrame:
58-
df_chunk["new_col"] = (
59-
(df_chunk["col1"] + df_chunk["col2"]) * factor + constant
58+
df["new_col"] = (
59+
(df["col1"] + df["col2"]) * factor + constant
6060
)
61-
return df_chunk
61+
return df
6262

6363
file_path = PATH_TO_AKUTILS_PKG / "tests" / "_fixtures" / "sales.csv"
6464
df = ak.read_csv_in_chunks(
6565
file_path,
6666
chunk_func=add_new_col_to_chunk,
67-
factor=2.4,
68-
constant=151,
67+
chunk_func_kwarg={
68+
"factor": 2.4,
69+
"constant": 151,
70+
},
6971
chunksize=5,
7072
sep=";",
7173
dtype=None
@@ -134,8 +136,8 @@ def test_read_multiple_csv_from_dir_with_chunk_function(self):
134136
Case with chunk function (the dir containing also not text file extension)
135137
"""
136138

137-
def filter_chunk(df_chunk: pd.DataFrame) -> pd.DataFrame:
138-
return df_chunk[df_chunk["nb_sales"] <= 4]
139+
def filter_chunk(df: pd.DataFrame) -> pd.DataFrame:
140+
return df[df["nb_sales"] <= 4]
139141

140142
df_expected = self.df_expected.copy()
141143
df_expected = df_expected[df_expected["nb_sales"] <= 4]

src/akutils/utils_functions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ def timeit_wrapper(*args, **kwargs):
1717
return timeit_wrapper
1818

1919

20+
def contruct_function_args_from_locals(function, locals_args):
21+
specified_args = {
22+
key: value for key, value in locals_args.items() if key not in ["kwargs"]
23+
}
24+
additionnal_kwargs = locals_args["kwargs"]
25+
all_args = dict(specified_args, **additionnal_kwargs)
26+
27+
# Filter on function alloewed args
28+
function_args = {
29+
key: value
30+
for key, value in all_args.items()
31+
if key in function.__code__.co_varnames
32+
}
33+
return function_args
34+
35+
2036
def sanitize_function_args_from_locals(function, locals_args):
2137
# Check if a function is passed, if not return empty dict
2238
if not hasattr(function, '__call__'):

0 commit comments

Comments
 (0)