Skip to content

Commit e118f0e

Browse files
committed
remove pandas in code
1 parent 2237cc8 commit e118f0e

3 files changed

Lines changed: 41 additions & 23 deletions

File tree

eval_protocol/pytest/utils.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929

3030
import logging
3131
import json
32-
import pandas as pd
32+
import random
33+
import statistics
3334

3435

3536
AggregationMethod = Literal["mean", "max", "min", "bootstrap"]
@@ -122,30 +123,25 @@ async def execute_run_with_progress(run_idx: int, config: RolloutProcessorConfig
122123
raise
123124

124125

125-
def calculate_bootstrap_scores(all_scores: list[float]) -> float:
126+
def calculate_bootstrap_scores(all_scores: list[float], n_boot: int = 100, seed: int | None = None) -> float:
126127
"""
127-
Calculate bootstrap confidence intervals for individual scores.
128+
Calculate the mean of bootstrap sample means for a list of scores.
128129
129130
Args:
130-
all_scores: List of individual scores from all rows
131+
all_scores: List of individual scores from all rows.
132+
n_boot: Number of bootstrap resamples to draw (default 100).
133+
seed: Optional RNG seed for reproducibility.
131134
132135
Returns:
133-
Mean bootstrap score
136+
Mean bootstrap score (float). Returns 0.0 if all_scores is empty.
134137
"""
135138
if not all_scores:
136139
return 0.0
137140

138-
# Create DataFrame (single column of scores)
139-
battles = pd.DataFrame({"score": all_scores})
140-
141-
# Bootstrap sampling for calculating relative performance
142-
bootstrap_means = [battles.sample(frac=1.0, replace=True)["score"].mean() for _ in range(100)]
143-
144-
# Calculate final scores
145-
bootstraps = pd.Series(bootstrap_means)
146-
mean_score = bootstraps.mean()
147-
148-
return float(mean_score)
141+
rng = random.Random(seed) if seed is not None else random
142+
k = len(all_scores)
143+
bootstrap_means = [statistics.fmean(rng.choices(all_scores, k=k)) for _ in range(n_boot)]
144+
return float(statistics.fmean(bootstrap_means))
149145

150146

151147
def aggregate(scores: list[float], method: AggregationMethod) -> float:

eval_protocol/quickstart/utils.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,10 @@
33
"""
44

55
import os
6-
from datetime import datetime
76
import re
8-
from typing import List, Dict, Any, Optional
9-
from openai import AsyncOpenAI
10-
import pandas as pd
7+
from typing import Dict, Any, Optional
118

12-
from eval_protocol.models import EvaluationRow, Message, EvaluateResult, MetricResult
13-
import asyncio
14-
from openai import OpenAI
9+
from eval_protocol.models import EvaluationRow, Message
1510

1611
OG_ARENA_HARD_PROMPT = """Please act as an impartial judge and evaluate the quality of the responses provided by two AI assistants to the user prompt displayed below. You will be given assistant A's answer and assistant B's answer. Your job is to evaluate which assistant's answer is better.
1712

tests/test_evaluation_postprocess.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,33 @@ def test_all_invalid_scores(self):
208208
assert mock_logger.log.call_count == 2
209209

210210

211+
class TestBootstrapEquivalence:
212+
def test_bootstrap_equivalence_pandas_vs_pure_python(self):
213+
import random
214+
import pandas as pd
215+
from eval_protocol.pytest.utils import calculate_bootstrap_scores as py_bootstrap
216+
217+
# Deterministic synthetic scores
218+
rng = random.Random(123)
219+
scores = [rng.random() for _ in range(100)]
220+
221+
n_boot = 1000
222+
seed = 42
223+
224+
# Old (pandas) style bootstrap: resample full column with replacement
225+
df = pd.DataFrame({"score": scores})
226+
pandas_means = [
227+
df.sample(frac=1.0, replace=True, random_state=seed + i)["score"].mean() for i in range(n_boot)
228+
]
229+
pandas_boot_mean = sum(pandas_means) / len(pandas_means)
230+
231+
# New pure-python implementation
232+
py_boot_mean = py_bootstrap(scores, n_boot=n_boot, seed=seed)
233+
234+
# They estimate the same quantity; allow small Monte Carlo tolerance
235+
assert abs(pandas_boot_mean - py_boot_mean) < 0.02
236+
237+
211238
class TestComputeFixedSetMuCi:
212239
"""Tests for compute_fixed_set_mu_ci function."""
213240

0 commit comments

Comments
 (0)