On approach is to read in the whole csv, and create groups based on where there are NaN in all 3 columns. Then create a dictionary based on those groups:
from io import StringIO
from pprint import pprint
import pandas as pd
df = pd.read_csv(StringIO('''demand;;;
1;4;3;2
2;3;4;2
3;3;3;4
4;4;3;2
workhours;;;
1;160;;
2;80;;
3;40;;
4;80;;
'''), sep=';', index_col=0, names=['column1', 'column2', 'column3'])
# Create Groups where all row values are NaN
groups = tuple(df.groupby((~df.index.str.isnumeric()).cumsum()))
dfs = {}
for i, (_, sub_df) in enumerate(groups):
# Get Name From Index as Key and set value as rest of the Frame
dfs[sub_df.index[0]] = sub_df.iloc[1:]
pprint(dfs)
dfs:
{'demand': column1 column2 column3
1 4.0 3.0 2.0
2 3.0 4.0 2.0
3 3.0 3.0 4.0
4 4.0 3.0 2.0,
'workhours': column1 column2 column3
1 160.0 NaN NaN
2 80.0 NaN NaN
3 40.0 NaN NaN
4 80.0 NaN NaN}
Some groupby options:
- Assuming that there are no rows with all NaNs except the row which where table breaks occur:
groups = tuple(df.groupby(df.isna().all(axis=1).cumsum()))
- Assuming that all indexes except the row where breaks occur are numeric:
groups = tuple(df.groupby((~df.index.str.isnumeric()).cumsum()))
- Assuming there are both occasionally non-numeric indexes and rows with NaNs, but that only rows where both occur are breaks:
groups = tuple(df.groupby((~df.index.str.isnumeric() & df.isna().all(axis=1)).cumsum()))