代码之家  ›  专栏  ›  技术社区  ›  fatdragon

熊猫通过取样读取csv

  •  0
  • fatdragon  · 技术社区  · 6 年前

    我有一个大的CSV文件,我只想从它采取1%的样本。有没有一种好方法可以直接将样本读入数据帧,而不必读取整个文件,然后丢弃99%的数据?

    1 回复  |  直到 6 年前
        1
  •  2
  •   J. Taylor    6 年前

    假设行数足够大,大#定律可以生效,并且不需要精确到1%(只是非常接近),可以执行以下操作:

    import csv
    from random import random
    import pandas
    with open('data.csv', 'r') as fin:
        reader = csv.reader(fin)
        rows = [l for l in reader if random() >= 0.99]
        df = pandas.DataFrame(rows)
    

    这将顺序扫描整个文件一次,以获得行,但它不会保留在内存中的整个文件。它将一行一行地迭代,并且只在内存中保留随机选择的~1%的行。如果您不想将文件加载到内存中,也不想先扫描它以计数行,那么这可能是最好的方法。

    如果您确实需要它正好占行数的1%,并且/或者需要它也适用于较小的文件,那么您可以扫描该文件一次,以计算文件中的总行数 total_lines . 然后生成一组 0.01 * total_lines set() 如果是的话就留着,否则就扔了:

    import csv
    import random
    import pandas
    with open('/home/jess/code/examples/testdata.csv', 'r') as fin:
        total_lines = sum(1 for line in fin)
        num_lines = int(0.01 * total_lines)
        selected_lines = set(random.sample(range(total_lines), num_lines))
        fin.seek(0) # reset cursor back to beginning of file for CSV reader
        reader = csv.reader(fin)
        rows = []
        curr_line = 0
        for row in reader:
            if curr_line in selected_lines:
                rows.append(row)
            curr_line += 1
    
        df = pandas.DataFrame(rows)
    
        2
  •  0
  •   gbronner    6 年前

    例如 rows=1000 prob=.01 print len(pd.read_csv(filename, usecols=[0], skiprows=lambda x: x in random.sample(xrange(0,num_rows), int((1.0-prob)*num_rows )))) 也有其他的方法来做它通过读在块,然后只是跳过行。 chunksize=100 skiprows=99