如何按百分比将列表切成三个部分?

8
我有一个文件列表,想将其分为三个部分:训练、验证和测试。我尝试了这段代码,但不确定它是否正确。
files = glob.glob("/dataset/%s/*" % emotion)
training = files[:int(len(files)*0.8)] #get first 80% of file list
validation = files[-int(len(files)*0.1):] #get middle 10% of file list
testing = files[-int(len(files)*0.1):] #get last 10% of file list

我不确定测试列表是否重复,或者它是否是文件列表的正确后10%。


这并不是说 len(files) == 3 就会导致索引变成 (2, 0, 0),而不是 (2, 1, 0) 或者 (2, 0, 1)。此外,验证和测试数据集应该是不同的,它们相等是不合适的(测试数据集应该是你从未接触过的数据)。 - Graipher
为了未来的读者添加。Numpy矩阵按百分比拆分 - Rex5
3个回答

21

您可以利用numpy split函数:

train, validate, test = np.split(files, [int(len(files)*0.8), int(len(files)*0.9)])

如果OP要求3个索引,为什么你只提供了2个索引?此外,添加一个自包含的示例会很有帮助。 - Charlie Parker
3
OP要求将数组分成三部分,使用np.split函数时需要指定两个索引值。除此之外,该回答已于三年前被接受,您认为编辑现在会有所帮助吗? - zipa
7
我发现了您在谷歌上非常有用的回答。因此,即使是三年后改进您的答案,也可能会帮助未来的读者。 - Mr.Epic Fail
@CharlieParker,您可以查看文档以获取有关如何使用语法的更多信息。https://numpy.org/doc/stable/reference/generated/numpy.split.html - dimas krisrianto

12

测试脚本是否与验证脚本重复?是的,您可以使用完全相同的方法创建它们,即提取最后10%进行验证和测试:

files = [1,2,3,4,5,6,7,8,9,10]
training = files[:int(len(files)*0.8)] #[1, 2, 3, 4, 5, 6, 7, 8]
validation = files[-int(len(files)*0.1):] #[10]
testing = files[-int(len(files)*0.1):] #[10]

如果你想坚持原来的方法(不过 np 方法更加优雅),我建议你做类似于这样的事情:

files = [1,2,3,4,5,6,7,8,9,10]
training = files[:int(len(files)*0.8)] #[1, 2, 3, 4, 5, 6, 7, 8]
validation = files[int(len(files)*0.8):int(len(files)*0.9)] #[9]
testing = files[int(len(files)*0.9):] #[10]

我尝试了你的答案,它也是正确的,谢谢。 - Oussama
我非常有兴趣做这件事,但是使用其他百分比,如70%,20%和10%。也许可以编写一个函数来定义其他百分比。谢谢! - ambigus9

5
与zipa的答案相同,但附带一个自包含的示例:
# splitting list of files into 3 train, val, test

import numpy as np

def split_two(lst, ratio=[0.5, 0.5]):
    assert(np.sum(ratio) == 1.0)  # makes sure the splits make sense
    train_ratio = ratio[0]
    # note this function needs only the "middle" index to split, the remaining is the rest of the split
    indices_for_splittin = [int(len(lst) * train_ratio)]
    train, test = np.split(lst, indices_for_splittin)
    return train, test

def split_three(lst, ratio=[0.8, 0.1, 0.1]):
    import numpy as np

    train_r, val_r, test_r = ratio
    assert(np.sum(ratio) == 1.0)  # makes sure the splits make sense
    # note we only need to give the first 2 indices to split, the last one it returns the rest of the list or empty
    indicies_for_splitting = [int(len(lst) * train_r), int(len(lst) * (train_r+val_r))]
    train, val, test = np.split(lst, indicies_for_splitting)
    return train, val, test

files = list(range(10))
train, test = split_two(files)
print(train, test)
train, val, test = split_three(files)
print(train, val, test)

输出:

[0 1 2 3 4] [5 6 7 8 9]
[0 1 2 3 4 5 6 7] [8] [9]

np.split 文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接