读取大型csv文件,python,pandas的随机行

时间:2016-07-06 21:02:21

标签: python pandas csv large-data

你能帮助我吗?我遇到了在大型csv文件中使用0.18.1 pandas和2.7.10 Python在Windows(8 Gb RAM)上读取随机行的问题。

Read a small random sample from a big CSV file into a Python data frame 我看到了一种方法,但是,我的PC出现了非常耗费内存的问题,即部分代码:

n = 100
s = 10
skip = sorted(rnd.sample(xrange(1, n), n-s))# skip n-s random rows from *.csv       
data = pd.read_csv(path, usecols = ['Col1', 'Col2'], 
                   dtype  = {'Col1': 'int32', 'Col2':'int32'}, skiprows = skip)

所以,如果我想从文件中获取一些随机行,不仅要考虑100行,而且要考虑100 000,那么它会变得很难,但是从文件中取出的随机行几乎没有问题:

skiprows = xrange(100000)    
data = pd.read_csv(path, usecols = ['Col1', 'Col2'], 
                   dtype  = {'Col1': 'int32', 'Col2':'int32'}, skiprows = skip, nrows = 10000)

所以问题是如何处理从大型csv文件中读取大量随机行的大熊猫,即因为我无法读取整个csv文件,即使使用分块,我也对随机行感兴趣。 感谢

2 个答案:

答案 0 :(得分:0)

如果内存是最大的问题,可能的解决方案可能是使用块,并从块中随机选择

n = 100
s = 10
factor = 1    # should be integer
chunksize = int(s/factor)

reader = pd.read_csv(path, usecols = ['Col1', 'Col2'],dtype  = {'Col1': 'int32', 'Col2':'int32'}, chunksize=chunksize)

out = []
tot = 0
for df in reader:
    nsample = random.randint(factor,chunksize)
    tot += nsample
    if  tot > s:
        nsample = s - (tot - nsample)
    out.append(df.sample(nsample))
    if tot >= s:
        break

data = pd.concat(out)

您可以使用因子来控制块的大小。

答案 1 :(得分:0)

我认为这比其他方法更快,可能值得一试。

比如说,我们已经在列表skipped中选择了要跳过的行。首先,我将其转换为查找bool表。

# Some preparation:
skipped = np.asarray(skipped)
# MAX >= number of rows in the file
bool_skipped = np.zeros(shape(MAX,), dtype=bool)
bool_skipped[skipped] = True

主要内容:

from io import StringIO
# in Python 2 use
# from StringIO import StringIO

def load_with_buffer(filename, bool_skipped, **kwargs):
    s_buf = StringIO()
    with open(filename) as file:
        count = -1
        for line in file:
            count += 1
            if bool_skipped[count]:
                continue
            s_buf.write(line)
    s_buf.seek(0)
    df = pd.read_csv(s_buf, **kwargs)
    return df

我按如下方式测试了它:

df = pd.DataFrame(np.random.rand(100000, 100))
df.to_csv('test.csv')

df1 = load_with_buffer('test.csv', bool_skipped, index_col=0)

跳过了90%的行。它的表现与

相当
pd.read_csv('test.csv', skiprows=skipped, index_col=0)

比使用dask或读取块大约快3-4倍。