SequencePreprocessor.pad_parts

static SequencePreprocessor.pad_parts(df_parts, length=None, gap='-', pad_at='C', list_parts=None)[source]

Pad sequence-part columns of a df_parts DataFrame to a uniform length with a gap symbol.

Application: Padding lets short or variable-length sequence parts (e.g. free peptides or linear epitopes with no flanking context) be analyzed at a uniform, finer resolution than the shortest real part allows. The in-house recipe is padCPP (with accept_gaps=True) → uniform n_split_max: a padded part has a longer string length, so CPP’s split validation permits a larger n_split_max (the Segment cap equals the part length) than the shortest original part would allow. The caveat is that padded positions carry the gap-scale value (NaN is omitted when accept_gaps=True) and therefore still feed into the computed features, so pad only as far as needed for the desired split resolution.

Added in version 1.1.0.

Parameters:
  • df_parts (pd.DataFrame, shape (n_samples, n_parts)) – DataFrame of sequence parts whose columns hold the amino acid sequences to pad.

  • length (int, optional) – Target length (>=1) to pad the selected columns to. If None, each selected column is padded to the maximum string length within that column (per-part). A sequence longer than length raises a ValueError because padding can only extend a sequence.

  • gap (str, default='-') – The single character used to represent gaps (padding).

  • pad_at (str, default='C') –

    Specifies where to add the padding:

    • ’N’ for N-terminus (beginning of the sequence),

    • ’C’ for C-terminus (end of the sequence),

    • ’both’ for symmetric (centered) padding: for k gaps, floor(k/2) are added at the N-terminus and the remaining k - floor(k/2) at the C-terminus.

  • list_parts (list of str or str, optional) – The names of the sequence-part column(s) to pad. If None (default), all columns are padded. Must be a subset of the df_parts columns; the non-selected columns are returned unchanged.

Returns:

df_parts_padded – A copy of df_parts with the selected columns padded to a uniform length; non-selected columns and the index are unchanged. The input DataFrame is never mutated.

Return type:

pd.DataFrame, shape (n_samples, n_parts)

Raises:

ValueError – If df_parts is not a DataFrame; if length is smaller than a selected sequence’s length (padding can only extend a sequence); if list_parts names a column not in df_parts; or if a selected column holds non-string values.

See also

  • CPP: whose accept_gaps=True mode consumes padded sequence parts to enable a uniform, finer n_split_max across variable-length sequences.

Examples

SequencePreprocessor().pad_parts() pads the sequence-part columns of a df_parts DataFrame to a uniform length by adding a gap symbol. It is the in-house way to bring short or variable-length parts (free peptides, linear epitopes, or any domain without flanking context) onto a common length.

When to reach for it. :class:~aaanalysis.CPP caps its splits to the shortest part it sees, so very short parts force a coarse n_split_max. Padding the parts to a uniform length lets :class:~aaanalysis.CPP (run with accept_gaps=True) use a finer, uniform ``n_split_max`` than the shortest real part would allow: a padded part is longer, so more Segment pieces fit. The caveat is that padded positions carry the gap-scale value (omitted from the computation when accept_gaps=True) and therefore still feed into the features, so pad only as far as needed for the desired split resolution.

import aaanalysis as aa
import pandas as pd

aa.options["verbose"] = False
sp = aa.SequencePreprocessor()

# A df_parts with short, variable-length parts (a 'tmd' and an 'jmd_n' column)
df_parts = pd.DataFrame({"tmd": ["LLIAGVL", "MIWLAVFG", "FYVGAML"],
                         "jmd_n": ["KK", "R", "QWE"]})
aa.display_df(df=df_parts, n_rows=10, show_shape=True)
DataFrame shape: (3, 2)
  tmd jmd_n
1 LLIAGVL KK
2 MIWLAVFG R
3 FYVGAML QWE

With length=None (default), each selected column is padded to the maximum string length within that column (per-part). A padded copy is returned; the input df_parts is never mutated and the index is preserved:

df_padded = sp.pad_parts(df_parts=df_parts, length=None)
aa.display_df(df=df_padded, n_rows=10, show_shape=True)
DataFrame shape: (3, 2)
  tmd jmd_n
1 LLIAGVL- KK-
2 MIWLAVFG R--
3 FYVGAML- QWE

Pass an explicit length to pad every selected column to that uniform length (which may be longer than the longest part). A part longer than length raises a ValueError because padding can only extend a sequence:

df_padded = sp.pad_parts(df_parts=df_parts, length=10)
aa.display_df(df=df_padded, n_rows=10, show_shape=True)
DataFrame shape: (3, 2)
  tmd jmd_n
1 LLIAGVL--- KK--------
2 MIWLAVFG-- R---------
3 FYVGAML--- QWE-------

By default all columns are padded. Use list_parts (a column name or a list of names) to pad only selected columns; the others are returned exactly as-is. Here only tmd is padded while jmd_n is left unchanged:

df_padded = sp.pad_parts(df_parts=df_parts, list_parts=["tmd"])
aa.display_df(df=df_padded, n_rows=10, show_shape=True)
DataFrame shape: (3, 2)
  tmd jmd_n
1 LLIAGVL- KK
2 MIWLAVFG R
3 FYVGAML- QWE

Change the single-character gap symbol (default -) used for padding:

df_padded = sp.pad_parts(df_parts=df_parts, length=10, gap="*")
aa.display_df(df=df_padded, n_rows=10, show_shape=True)
DataFrame shape: (3, 2)
  tmd jmd_n
1 LLIAGVL*** KK********
2 MIWLAVFG** R*********
3 FYVGAML*** QWE*******

pad_at places the gaps at the C-terminus (end, default), the N-terminus (beginning), or both (symmetric/centered). With both, for k gaps needed, floor(k/2) are added at the N-terminus and the remaining k - floor(k/2) at the C-terminus. Below the same tmd column is padded three ways for comparison:

df_c = sp.pad_parts(df_parts=df_parts, length=10, pad_at="C", list_parts=["tmd"])
df_n = sp.pad_parts(df_parts=df_parts, length=10, pad_at="N", list_parts=["tmd"])
df_both = sp.pad_parts(df_parts=df_parts, length=10, pad_at="both", list_parts=["tmd"])

df_compare = pd.DataFrame({"original": df_parts["tmd"],
                           "pad_at='C'": df_c["tmd"],
                           "pad_at='N'": df_n["tmd"],
                           "pad_at='both'": df_both["tmd"]})
aa.display_df(df=df_compare, n_rows=10, show_shape=True)
DataFrame shape: (3, 4)
  original pad_at='C' pad_at='N' pad_at='both'
1 LLIAGVL LLIAGVL--- ---LLIAGVL -LLIAGVL--
2 MIWLAVFG MIWLAVFG-- --MIWLAVFG -MIWLAVFG-
3 FYVGAML FYVGAML--- ---FYVGAML -FYVGAML--

The motivating use case. We start from four short TMD peptides (shortest original length 7), pad the tmd column to a uniform length of 10, and run :class:~aaanalysis.CPP with accept_gaps=True at n_split_max=10 — larger than the shortest original part. Without padding, :class:~aaanalysis.CPP would auto-cap the Segment split to 7; padding lets the finer Segment(..,10) splits appear in df_feat:

list_tmd = ["LLIAGVL", "MIWLAVFG", "FYVGAML", "ILMAWVFG"]
labels = [1, 1, 0, 0]
print("shortest original length:", min(len(s) for s in list_tmd))

# Pad the 'tmd' column to a uniform length of 10 (finer than the shortest original 7)
df_parts_short = pd.DataFrame({"tmd": list_tmd})
df_parts_padded = sp.pad_parts(df_parts=df_parts_short, length=10, list_parts=["tmd"])
aa.display_df(df=df_parts_padded, n_rows=10, show_shape=True)
shortest original length: 7
DataFrame shape: (4, 1)
  tmd
1 LLIAGVL---
2 MIWLAVFG--
3 FYVGAML---
4 ILMAWVFG--
# n_split_max=10 is larger than the shortest ORIGINAL part (7)
sf = aa.SequenceFeature()
split_kws = sf.get_split_kws(n_split_max=10, split_types=["Segment"])
cpp = aa.CPP(df_parts=df_parts_padded, split_kws=split_kws, accept_gaps=True)
df_feat = cpp.run(labels=labels, n_filter=10)
aa.display_df(df=df_feat, n_rows=10, show_shape=True)
/Users/stephanbreimann/Programming/1Packages/wt-338-gap/aaanalysis/feature_engineering/_cpp.py:54: UserWarning: 'accept_gaps' (True) encountered the gap symbol ('-') in 'df_parts'; affected feature values may be NaN. Ensure downstream scorers handle NaN.
  warnings.warn(
DataFrame shape: (10, 13)
  feature category subcategory scale_name scale_description abs_auc abs_mean_dif mean_dif std_test std_ref p_val_mann_whitney p_val_fdr_bh positions
1 TMD-Segment(1,10)-VASM830103 Conformation Unclassified (Conformation) Extended Relative popula...z et al., 1983) 0.500000 0.714000 -0.714000 0.084000 0.074000 0.121335 1.000000 11,12
2 TMD-Segment(3,10)-TANS770102 Conformation α-helix (C-term, out) α-helix (C-terminal, outside) Normalized freq...Scheraga, 1977) 0.500000 0.646000 0.646000 0.148000 0.094000 0.121335 0.385545 15,16
3 TMD-Segment(1,10)-VASM830102 Energy Non-bonded energy Free energy (Extended) Relative popula...z et al., 1983) 0.500000 0.595000 0.595000 0.130000 0.024000 0.121335 0.387839 11,12
4 TMD-Segment(3,10)-KARS160112 Shape Graph (2. eigenvalue) Eigenvalue (2. smallest) Second smallest...-Knisley, 2016) 0.500000 0.590000 -0.590000 0.080000 0.176000 0.121335 0.391726 15,16
5 TMD-Segment(3,10)-SUEM840102 Structure-Activity Unclassified (S...cture-Activity) Stability (extended-coil) Zimm-Bragg para...i et al., 1984) 0.500000 0.506000 0.506000 0.143000 0.350000 0.121335 0.394095 15,16
6 TMD-Segment(3,5)-CHAM830108 Energy Charge Charge (donor) A parameter of ...-Charton, 1983) 0.500000 0.500000 -0.500000 0.000000 0.000000 0.121335 0.396493 19,20,21,22
7 TMD-Segment(3,10)-GOLD730101 Polarity Hydrophobicity Hydrophobicity Hydrophobicity ...halifoux, 1973) 0.500000 0.492000 0.492000 0.008000 0.067000 0.121335 0.397299 15,16
8 TMD-Segment(3,10)-PONP800105 Polarity Hydrophobicity (surrounding) Surrounding hydrophobicity Surrounding hyd...y et al., 1980) 0.500000 0.482000 -0.482000 0.021000 0.008000 0.121335 0.380294 15,16
9 TMD-Segment(1,10)-PONP800105 Polarity Hydrophobicity (surrounding) Surrounding hydrophobicity Surrounding hyd...y et al., 1980) 0.500000 0.472000 0.472000 0.028000 0.009000 0.121335 0.367427 11,12
10 TMD-Segment(1,10)-QIAN880128 Conformation Coil (N-term) Coil (N-terminal) Weights for coi...ejnowski, 1988) 0.500000 0.470000 0.470000 0.066000 0.078000 0.121335 0.363329 11,12

The resulting df_feat contains features such as TMD-Segment(1,10) and TMD-Segment(3,10) — splits into 10 pieces, a finer resolution than the shortest original part (length 7) could support on its own.