Skip to content

Metadata

neureptrace.metadata

add_binary_label(metadata, *, source_column, positive_pattern, label_column, negative_pattern=None, positive_label='positive', negative_label='negative', case_sensitive=False)

Add a binary label column by matching text patterns in an existing column.

When negative_pattern is omitted, every non-null source value that does not match positive_pattern receives the negative label. When negative_pattern is provided, unmatched rows receive missing labels and rows that match both patterns keep the positive label.

Source code in src/neureptrace/metadata.py
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
def add_binary_label(
    metadata: pd.DataFrame,
    *,
    source_column: str,
    positive_pattern: str,
    label_column: str,
    negative_pattern: str | None = None,
    positive_label: str = "positive",
    negative_label: str = "negative",
    case_sensitive: bool = False,
) -> pd.DataFrame:
    """Add a binary label column by matching text patterns in an existing column.

    When ``negative_pattern`` is omitted, every non-null source value that does
    not match ``positive_pattern`` receives the negative label. When
    ``negative_pattern`` is provided, unmatched rows receive missing labels and
    rows that match both patterns keep the positive label.
    """
    source_column = _non_empty_text(source_column, name="source_column")
    label_column = _non_empty_text(label_column, name="label_column")
    case_sensitive = _boolean(case_sensitive, name="case_sensitive")
    positive_regex = _compile_pattern(positive_pattern, name="positive_pattern", case_sensitive=case_sensitive)
    negative_regex = None if negative_pattern is None else _compile_pattern(negative_pattern, name="negative_pattern", case_sensitive=case_sensitive)
    positive_label, negative_label = _validate_binary_labels(positive_label, negative_label)

    if source_column not in metadata.columns:
        raise ValueError(f"Source column '{source_column}' not found in metadata.")
    source = metadata[source_column]
    if isinstance(source, pd.DataFrame):
        raise ValueError(f"Source column '{source_column}' must identify exactly one metadata column.")
    if label_column in metadata.columns:
        raise ValueError(f"Label column '{label_column}' already exists.")

    source = source.astype("string")
    positive = source.str.contains(positive_regex, regex=True, na=False)
    if negative_regex is None:
        negative = source.notna() & ~positive
    else:
        negative = source.str.contains(negative_regex, regex=True, na=False) & ~positive

    labeled = metadata.copy()
    labeled[label_column] = pd.NA
    labeled.loc[positive, label_column] = positive_label
    labeled.loc[negative, label_column] = negative_label
    return labeled

prepare_binary_metadata(events_csv, out_path, *, source_column, positive_pattern, label_column, negative_pattern=None, positive_label='positive', negative_label='negative', case_sensitive=False)

Load metadata, add a binary label, and write the result as CSV.

Source code in src/neureptrace/metadata.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def prepare_binary_metadata(
    events_csv: Path,
    out_path: Path,
    *,
    source_column: str,
    positive_pattern: str,
    label_column: str,
    negative_pattern: str | None = None,
    positive_label: str = "positive",
    negative_label: str = "negative",
    case_sensitive: bool = False,
) -> pd.DataFrame:
    """Load metadata, add a binary label, and write the result as CSV."""
    metadata = pd.read_csv(events_csv)
    labeled = add_binary_label(
        metadata,
        source_column=source_column,
        positive_pattern=positive_pattern,
        negative_pattern=negative_pattern,
        label_column=label_column,
        positive_label=positive_label,
        negative_label=negative_label,
        case_sensitive=case_sensitive,
    )
    out_path.parent.mkdir(parents=True, exist_ok=True)
    labeled.to_csv(out_path, index=False)
    return labeled