【问题标题】:Python: How to sample data into Test and Train datasets?Python:如何将数据采样到测试和训练数据集中?
【发布时间】:2016-03-15 20:28:28
【问题描述】:

我一直在使用 CSV 数据来实现我的脚本,并希望将数据采样到两个数据集中:

  1. 测试数据
  2. 火车数据

我想以 85% 和 15% 的分区对数据集进行采样,并希望输出两个 CSV 文件 Test.csv 和 Train.csv

我希望它在基础 Python 中执行,并且不想使用任何其他外部模块,如 Numpy、SciPy、Pandas 或 Scikitlearn。任何人都可以帮助我按百分比随机抽样数据。此外,我将获得可能具有随机数量观察的数据集。到目前为止,我刚刚阅读了有关 Pandas 和其他各种模块以按百分比对数据进行采样,但还没有针对我的问题找到任何具体的解决方案。

此外,我想在两个文件中保留 CSV 的标题。因为标题会使每一行都可以访问,并且可以用于进一步的分析。

【问题讨论】:

  • 您的帖子非常广泛。详细说明您已经尝试过的内容。使用问号明确您要问的问题。
  • @MartinCowie 我刚刚研究过网络搜索。到目前为止没有尝试过任何东西。正在搜索逻辑,我想从现有文件创建两个文件。 Test.csvTrain.csv 来自主文件 data.csv 我希望 85% 的数据应该在 test.csv 中,其余 15% 的数据在 train.csv
  • 为什么要 85% 的数据作为测试数据,15% 作为训练数据?很可能您需要 85% 的数据用于训练并保留作为测试数据。

标签: python csv random-sample


【解决方案1】:

使用random module中的random函数得到01之间均匀分布的随机数。

如果是> .85,则写入训练数据,否则写入测试数据。见How do I simulate flip of biased coin in python?

import random

with open(input_file) as data:
    with open(test_output, 'w') as test:
        with open(train_output, 'w') as train:
            header = next(data)
            test.write(header)
            train.write(header)
            for line in data:
                if random.random() > 0.85:
                    train.write(line)
                else:
                    test.write(line)

【讨论】:

  • csv.writer 没有名为“write”的对象,我认为它应该是 writerows ?
  • 脱帽致敬!但数据也包含标题。并且标题出现在一个文件中,而不是在第二个文件中。以任何方式保留两个文件中的标题
  • @desmond.carros: csv.DictReadercsv.DictWriter 在这种情况下可能很有用。
  • 我也是这么想的。 :)
  • @desmond.carros 将其放入问题中,或询问/搜索其他问题。
【解决方案2】:

使用 random.shuffle 创建数据集的随机排列并根据需要对其进行切片:

import random
random.shuffle(data)
train = data[:int(len(data)*0.85)]
test = data[len(train):]

由于您要求使用特定解决方案将可能较大的 CSV 文件划分为两个文件以用于训练和测试数据,因此我还将展示如何使用类似于上述一般方法的方法来完成此操作:

import random

# Count lines
with open('data.csv','r') as csvf:
    linecount = sum(1 for lines in csvf if line.strip() != '')

# Create index sets for training and test data
indices = list(range(linecount))
random.shuffle(indices)
ind_test = set(indices[:int(linecount*0.15)])
del indices

# Partition CSV file
with open('data.csv','r') as csvf, open('train.csv','w') as trainf, open('test.csv','w') as testf:
    i = 0
    for line in csvf:
        if line.strip() != '':
            if i in ind_test:
                testf.write(line.strip() + '\n')
            else:
                trainf.write(line.strip() + '\n')

因此,我假设 CSV 文件每行包含一个观察结果。

这将创建一个准确的 85:15 分割。如果不太准确的分区适合您,那么 Peter Wood 的解决方案会更有效率。

【讨论】:

  • “CSV 数据”是什么意思?您没有在问题中提到如何存储数据,所以我只是假设 data 是一系列观察结果。
  • 对不起,如果我没有提到。但截至目前,我的数据是 CSV 格式,我希望对数据进行相应的采样。但无论如何,谢谢。 :)
  • @desmond.carros 您的 CSV 文件有多大?这期望它们同时都在内存中。
  • @PeterWood CSV 文件可能以千兆字节为单位,即它可能包含数百万或更多条目。
猜你喜欢
  • 2019-05-01
  • 2017-02-20
  • 2021-12-08
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 2017-09-30
相关资源
最近更新 更多