我正在使用Kaggle样本数据。如下所示,40% 的位置位于 CA
,47% 的 category
包括 FOODS
。我想要实现的是从该数据框中随机选择数据,同时或多或少保留这两列的值的相同分布。 python/Pandas有这样的能力吗?
>>> df = pd.read_parquet("~/dimension.parquet")
>>> df.groupby('location')['location'].count().transform(lambda x: x/x.sum())
location
CA 0.4
TX 0.3
WI 0.3
>>> df.groupby('category')['category'].count().transform(lambda x: x/x.sum())
category
FOODS 0.471302
HOBBIES 0.185307
HOUSEHOLD 0.343391
最佳答案
您可以使用 groupby.sample
选择每个组的一部分:
# selecting 10% of each group
df.groupby(['location', 'category']).sample(frac=0.1)
但是,如果您的数据很大并且选择了相当多的行,那么这自然应该保持比例的代表性:
df.sample(n=1000)
例如,让我们从 1M 行中选择具有定义频率的 500 (0.05%) 或 5000 (0.5%) 行:
np.random.seed(0)
n = 1_000_000
df = pd.DataFrame({'location': np.random.choice(['CA', 'TX', 'WI'], p=[0.4, 0.3, 0.3], size=n),
'category': np.random.choice(['A', 'B', 'C'], p=[0.85, 0.1, 0.05], size=n)})
out = df.sample(n=500)
out['location'].value_counts(normalize=True)
CA 0.388
TX 0.312
WI 0.300
Name: location, dtype: float64
out['category'].value_counts(normalize=True)
A 0.822
B 0.126
C 0.052
Name: category, dtype: float64
使用df.sample(n=5000)
:
CA 0.3984
TX 0.3064
WI 0.2952
Name: location, dtype: float64
A 0.8468
B 0.1042
C 0.0490
Name: category, dtype: float64
原始总体的频率:
CA 0.399295
WI 0.300520
TX 0.300185
Name: location, dtype: float64
A 0.850125
B 0.099679
C 0.050196
Name: category, dtype: float64
我们观察到,两个样本都相当能代表原始总体,但较小的样本会造成一些精度损失。
相比之下,groupby.sample
即使样本非常小(此处大约 200 行 (0.02%))也能保持接近原始的比例:
out2 = df.groupby(['location', 'category']).sample(frac=0.0002)
print(out2['location'].value_counts(normalize=True))
print(out2['category'].value_counts(normalize=True))
len(out2)
CA 0.4
TX 0.3
WI 0.3
Name: location, dtype: float64
A 0.85
B 0.10
C 0.05
Name: category, dtype: float64
200
关于python - 如何从数据框中随机采样,同时保留 Python 中的分布?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74397847/