Skip to content

样本敏感性

按确切数量、保护规则和面板个体生成样本。

核心代码

py
    def sample_ids(self, spec):
        sample = spec.get('sample') or {'kind': 'none'}
        frame = self.reference
        c, kind = self.config, sample['kind']
        protected = set(c['protected_rows'])
        if c['entity']:
            protected.update(frame.index[frame[c['entity']].astype(str).isin(c['protected_entities'])].tolist())
        if kind == 'none':
            return self.ref_ids
        if kind == 'drop_rows':
            drop = set(sample['values'])
        elif kind == 'drop_entities':
            drop = set(frame.index[frame[c['entity']].astype(str).isin(sample['values'])])
        elif kind == 'short_panels':
            sizes = frame.groupby(c['entity'])[c['entity']].transform('size')
            drop = set(frame.index[sizes < sample['minimum']])
        elif kind in ('random_rows', 'random_entities'):
            rng = np.random.default_rng(sample['seed'])
            if kind == 'random_rows':
                pool = sorted(set(self.ref_ids) - protected)
                n = int(len(frame) * sample['drop_fraction'])
                if n > len(pool):
                    raise ExplorationError('protected_sample')
                drop = set(map(int, rng.choice(pool, n, replace=False)))
            else:
                entities = sorted(frame[c['entity']].astype(str).unique())
                locked = set(frame.loc[frame.index.isin(protected), c['entity']].astype(str))
                pool = sorted(set(entities) - locked)
                n = int(len(entities) * sample['drop_fraction'])
                if n > len(pool):
                    raise ExplorationError('protected_sample')
                chosen = list(rng.choice(pool, n, replace=False))
                drop = set(frame.index[frame[c['entity']].astype(str).isin(chosen)])
        else:
            raise ExplorationError('invalid_sample')
        if drop & protected:
            raise ExplorationError('protected_sample')
        return [i for i in self.ref_ids if i not in drop]

Released under the AGPL-3.0 License.