这是一个机器学习程序。
我正在处理一个数据集,该数据集有一个csv,其中包含另一个目录中.tif
映像的id和一个标签1或0。csv中有220025行。我已经将这个csv加载为pandas数据帧。目前在数据帧中,有220025行,其中130908行带有标签0,89117行带有标签1。
标签为0的行比标签为1的行多41791行。我想随机删除标签为1的额外行。之后,我想将样本量从178234减少到50000,每个标签有25000个ID。
另一种方法可以是随机丢弃具有标签1的105908行和具有标签0的64117行。
我怎么能用熊猫做到这一点?
我已经考虑过使用.groupby
,然后使用.sample
,但这会在两个标签中减少相等数量的行,而我只想在一个标签中删除行。
csv示例:
id,label
f38a6374c348f90b587e046aac6079959adf3835,0
c18f2d887b7ae4f6742ee445113fa1aef383ed77,1
755db6279dae599ebb4d39a9123cce439965282d,0
bc3f0c64fb968ff4a8bd33af6971ecae77c75e08,0
068aba587a4950175d04c680d38943fd488d6a9d,0
acfe80838488fae3c89bd21ade75be5c34e66be7,0
a24ce148f6ffa7ef8eefb4efb12ebffe8dd700da,1
7f6ccae485af121e0b6ee733022e226ee6b0c65f,1
559e55a64c9ba828f700e948f6886f4cea919261,0
8eaaa7a400aa79d36c2440a4aa101cc14256cda4,0
就我个人而言,我会将其分解为以下步骤:
由于0比1多,我们首先要确保每个0的数量相等。在这里,我使用您粘贴的示例数据作为df
- 计算1的数量(因为这是我们的较小值(
ones_subset = df.loc[df["label"] == 1, :]
number_of_1s = len(ones_subset)
print(number_of_1s)
3
- 仅对零进行采样以匹配
number_of_1s
的数量
zeros_subset = df.loc[df["label"] == 0, :]
sampled_zeros = zeros_subset.sample(number_of_1s)
print(sampled_zeros)
- 将这两个块(来自我们的
ones_subset
和匹配的sampled_zeros
的所有1(粘在一起,形成一个具有相等数量的1和0标签的干净数据帧
clean_df = pd.concat([ones_subset, sampled_zeros], ignore_index=True)
print(clean_df)
id label
0 c18f2d887b7ae4f6742ee445113fa1aef383ed77 1
1 a24ce148f6ffa7ef8eefb4efb12ebffe8dd700da 1
2 7f6ccae485af121e0b6ee733022e226ee6b0c65f 1
3 559e55a64c9ba828f700e948f6886f4cea919261 0
4 f38a6374c348f90b587e046aac6079959adf3835 0
5 068aba587a4950175d04c680d38943fd488d6a9d 0
现在我们有了一个清理过的数据集,我们可以继续进行最后一步:
- 使用您提到的
groupby(...).sample(...)
方法对该数据集进行进一步的下采样。从一个每个标签有3个(三个1和三个0(的数据集中得到一个较小的匹配大小(两个1和两个0(
downsampled_df = clean_df.groupby("label").sample(2)
print(downsampled_df)
id label
4 f38a6374c348f90b587e046aac6079959adf3835 0
5 068aba587a4950175d04c680d38943fd488d6a9d 0
1 a24ce148f6ffa7ef8eefb4efb12ebffe8dd700da 1
0 c18f2d887b7ae4f6742ee445113fa1aef383ed77 1