diff --git a/prwlr/core.py b/prwlr/core.py
index e0b5859..146c0bd 100644
--- a/prwlr/core.py
+++ b/prwlr/core.py
@@ -1,7 +1,17 @@
 import pandas as _pd
 import numpy as _np
 from . import databases
+from . import profiles as _profiles
 
+class Columns:
+    """
+    Container for the columns names defined in this module.
+    """
+    SPLIT_SUF = '_SPLIT'
+    REF = 'REF'
+    QRY = 'QRY'
+    REF_SPLIT = '{}{}'.format(REF, SPLIT_SUF)
+    QRY_SPLIT = '{}{}'.format(QRY, SPLIT_SUF)
 
 def get_IDs_names(
     species,
@@ -98,6 +108,55 @@ def read_sga(
     sga.parse(filename=filename)
     return sga.sga
 
+def read_profiles(
+    filename,
+    reference_column=Columns.REF,
+    query_column=Columns.QRY,
+    str_sep='|',
+    **kwargs
+):
+    """
+    Returns pandas.Series with prwlr.profiles.Profile objects from CSV.
+
+    Parameters
+    -------
+    filename: str, path
+        Filename of the CSV.
+    """
+    ref_qry_df = _pd.read_csv(filename, **kwargs)
+    ref_qry_df[Columns.REF_SPLIT] = ref_qry_df[Columns.REF].str.split(str_sep)
+    ref_qry_df[Columns.QRY_SPLIT] = ref_qry_df[Columns.QRY].str.split(str_sep)
+    return ref_qry_df[[Columns.REF_SPLIT, Columns.QRY_SPLIT]].apply(
+        lambda x: _profiles.Profile(
+            reference=x[Columns.REF_SPLIT],
+            query=x[Columns.QRY_SPLIT],
+        ),
+        axis=1,
+    )
+
+def save_profiles(
+    series,
+    filename,
+    reference_column=Columns.REF,
+    query_column=Columns.QRY,
+    str_sep='|',
+    **kwargs
+):
+    """
+    Writes pandas.Series with prwlr.profiles.Profile objects to CSV file.
+
+    Parameters
+    -------
+    Filename: str, path
+        Name of the file.
+    """
+    _pd.DataFrame(
+        {
+            Columns.REF: series.apply(lambda x: x.reference).str.join(str_sep),
+            Columns.QRY: series.apply(lambda x: x.query).str.join(str_sep),
+        },
+    ).to_csv(filename, **kwargs)
+
 def merge_sga_profiles(
     sga,
     profiles

prwlr.read_profiles
The highest-level convenience method ```prwlr.read_profiles``` should be implemented in ```prwlr.core``` analogous to ```prwlr.core.read_sga```. There should be also be ```prwlr.save_profiles``` avilable.
diff --git a/test_data/CoreTests/test_profiles.csv b/test_data/CoreTests/test_profiles.csv
new file mode 100644
index 0000000..ce9fafc
--- /dev/null
+++ b/test_data/CoreTests/test_profiles.csv
@@ -0,0 +1,3 @@
+,QRY,REF
+0,a|c|d|f|h|i|k|l|o|s|t|u|z,b|c|e|f|g|h|i|j|k|l|m|n|p|r|s|t|u|w|x|y
+1,a|b|d|f|h|i|k|l|o|s|t|u|z,a|c|e|f|g|h|i|j|k|l|m|n|p|r|s|t|u|w|x|y
diff --git a/tests/tests.py b/tests/tests.py
index 315bd8d..b6b2a42 100644
--- a/tests/tests.py
+++ b/tests/tests.py
@@ -605,5 +605,76 @@ class StatsTests(unittest.TestCase):
                         650)
 
 
+class CoreTests(unittest.TestCase):
+    """
+    Tests of prwlr.core functions.
+    """
+    def setUp(self):
+        """
+        Sets up class level attributes for the tests.
+        """
+        import prwlr.core
+
+        self.ref_reference_1 = list('bcefghijklmnprstuwxy')
+        self.ref_query_1 = list('acdfhiklostuz')
+        self.ref_reference_2 = list('acefghijklmnprstuwxy')
+        self.ref_query_2 = list('abdfhiklostuz')
+        self.test_profiles_filename = 'test_data/CoreTests/test_profiles.csv'
+        self.test_saved_profiles_filename = 'test_data/CoreTests/test_save_profiles.csv'
+
+        self.ref_profile_1, self.ref_profile_2 = (
+            prwlr.profiles.Profile(
+                reference=self.ref_reference_1,
+                query=self.ref_query_1,
+            ),
+            prwlr.profiles.Profile(
+                reference=self.ref_reference_2,
+                query=self.ref_query_2,
+            ),
+        )
+        self.ref_profiles_srs = pd.Series(
+            [self.ref_profile_1, self.ref_profile_2],
+        )
+
+        self.test_profiles_srs = prwlr.core.read_profiles(
+            self.test_profiles_filename,
+            index_col=[0],
+        )
+
+        prwlr.core.save_profiles(
+            self.ref_profiles_srs,
+            self.test_saved_profiles_filename,
+        )
+        self.test_profiles_after_save_srs = prwlr.core.read_profiles(
+            self.test_saved_profiles_filename,
+            index_col=[0],
+        )
+
+    def tearDown(self):
+        """
+        Removes files created during the tests.
+        """
+        os.remove(self.test_saved_profiles_filename)
+
+    def test_read_profiles(self):
+        """
+        Tests if prwlr.core.read_profiles returns pandas.Series with correct
+        prwlr.profiles.Profile objects.
+        """
+        pd.testing.assert_series_equal(
+            self.ref_profiles_srs,
+            self.test_profiles_srs,
+        )
+
+    def test_save_profiles(self):
+        """
+        Tests if prwlr.core.save_profiles writes CSV file with correct values.
+        """
+        pd.testing.assert_series_equal(
+            self.ref_profiles_srs,
+            self.test_profiles_after_save_srs,
+        )
+
+
 if __name__ == '__main__':
     unittest.main()

pip install -e .
parse_log_pytest
requirements.txt
nose pytest
apt-get update apt-get install -y gcc
3.6
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
charset-normalizer==2.0.12
cycler==0.11.0
decorator==4.4.2
dill==0.3.4
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
kiwisolver==1.3.1
matplotlib==3.3.4
multiprocess==0.70.12.2
networkx==2.5.1
nose==1.3.7
numpy==1.19.5
packaging==21.3
pandas==1.1.5
pathos==0.2.8
Pillow==8.4.0
pluggy==1.0.0
pox==0.3.0
ppft==1.6.6.4
-e git+https://github.com/dizak/prwlr.git@e16a0c808ea160a3480dff39ec1527d1f5f971e5#egg=prwlr
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
scipy==1.5.4
six==1.17.0
tomli==1.2.3
tqdm==4.64.1
typing_extensions==4.1.1
urllib3==1.26.20
xlrd==2.0.1
zipp==3.6.0

name: prwlr
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - charset-normalizer==2.0.12
      - cycler==0.11.0
      - decorator==4.4.2
      - dill==0.3.4
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - kiwisolver==1.3.1
      - matplotlib==3.3.4
      - multiprocess==0.70.12.2
      - networkx==2.5.1
      - nose==1.3.7
      - numpy==1.19.5
      - packaging==21.3
      - pandas==1.1.5
      - pathos==0.2.8
      - pillow==8.4.0
      - pluggy==1.0.0
      - pox==0.3.0
      - ppft==1.6.6.4
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - scipy==1.5.4
      - six==1.17.0
      - tomli==1.2.3
      - tqdm==4.64.1
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - xlrd==2.0.1
      - zipp==3.6.0
prefix: /opt/conda/envs/prwlr

tests/tests.py::CoreTests::test_read_profiles tests/tests.py::CoreTests::test_save_profiles
tests/tests.py::DatabasesTests::test_parse_database tests/tests.py::BioprocessesTests::test_parse
tests/tests.py::UtilsTests::test_all_possible_combinations_counter tests/tests.py::UtilsTests::test_isiniterable tests/tests.py::UtilsTests::test_remove_char tests/tests.py::UtilsTests::test_remove_from_list tests/tests.py::ApisTests::test_get_KOs_db_X_ref tests/tests.py::ApisTests::test_get_org_db_X_ref tests/tests.py::ApisTests::test_get_organisms_ids tests/tests.py::ApisTests::test_org_name_2_kegg_id tests/tests.py::CostanzoAPITests::test_get_data tests/tests.py::DatabasesTests::test_parse_organism_info tests/tests.py::SGA1Tests::test_parse tests/tests.py::SGA2Tests::test_parse tests/tests.py::AnyNetworkTests::test_parse tests/tests.py::ProfileTests::test___eq__ tests/tests.py::ProfileTests::test__bind tests/tests.py::ProfileTests::test__convert tests/tests.py::ProfileTests::test_calculate_pss tests/tests.py::ProfileTests::test_calculate_pss_ignore tests/tests.py::ProfileTests::test_get_absent tests/tests.py::ProfileTests::test_get_present tests/tests.py::ProfileTests::test_isall tests/tests.py::ProfileTests::test_isany tests/tests.py::ProfileTests::test_to_array tests/tests.py::ProfileTests::test_to_list tests/tests.py::ProfileTests::test_to_series tests/tests.py::ProfileTests::test_to_string tests/tests.py::ProfileTests::test_to_tuple tests/tests.py::StatsTests::test_binomial_pss_test
prwlr/core.py
prwlr/core.py