读取大型 csv 文件的随机行,python,pandas
Reading random rows of a large csv file, python, pandas
你能帮我吗,我遇到了使用 0.18.1 pandas 和 2.7.10 Python 从大型 csv 文件读取随机行的问题 Windows (8 Gb内存)。
在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)
所以问题是如何使用 pandas 处理从大型 csv 文件中读取大量随机行,即因为我无法读取整个 csv 文件,即使将其分块,我'我对随机行完全感兴趣。
谢谢
如果内存是最大的问题,一个可能的解决方案可能是使用块,并从块
中随机 select
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)
并且您可以使用因子来控制块的大小。
我认为这比此处显示的其他方法更快,可能值得一试。
比如说,我们已经在列表中选择了要跳过的行 skipped
。首先,我将其转换为查找布尔 table.
# 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 倍。
你能帮我吗,我遇到了使用 0.18.1 pandas 和 2.7.10 Python 从大型 csv 文件读取随机行的问题 Windows (8 Gb内存)。
在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)
所以问题是如何使用 pandas 处理从大型 csv 文件中读取大量随机行,即因为我无法读取整个 csv 文件,即使将其分块,我'我对随机行完全感兴趣。 谢谢
如果内存是最大的问题,一个可能的解决方案可能是使用块,并从块
中随机 selectn = 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)
并且您可以使用因子来控制块的大小。
我认为这比此处显示的其他方法更快,可能值得一试。
比如说,我们已经在列表中选择了要跳过的行 skipped
。首先,我将其转换为查找布尔 table.
# 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 倍。