Python chunk读取超大文件

16GB小水存已经不能适应动辄4GB、8GB的数据文件了。

查询到pandas的read_csv()提供了chunk分块读取能力。

 

官方示例

 

这是一张原始的table

In [185]: table = pd.read_csv('tmp.sv', sep='|')

In [186]: table
Out[186]: 
   Unnamed: 0         0         1         2         3
0           0  0.469112 -0.282863 -1.509059 -1.135632
1           1  1.212112 -0.173215  0.119209 -1.044236
2           2 -0.861849 -2.104569 -0.494929  1.071804
3           3  0.721555 -0.706771 -1.039575  0.271860
4           4 -0.424972  0.567020  0.276232 -1.087401
5           5 -0.673690  0.113648 -1.478427  0.524988
6           6  0.404705  0.577046 -1.715002 -1.039268
7           7 -0.370647 -1.157892 -1.344312  0.844885
8           8  1.075770 -0.109050  1.643563 -1.469388
9           9  0.357021 -0.674600 -1.776904 -0.968914

 

指定chunksize=4,表明每4行为1个chunk。

In [187]: reader = pd.read_csv('tmp.sv', sep='|', chunksize=4)

In [188]: reader
Out[188]: <pandas.io.parsers.TextFileReader at 0x7f2b428c17f0>

In [189]: for chunk in reader:
   .....:     print(chunk)
   .....: 
   Unnamed: 0         0         1         2         3
0           0  0.469112 -0.282863 -1.509059 -1.135632
1           1  1.212112 -0.173215  0.119209 -1.044236
2           2 -0.861849 -2.104569 -0.494929  1.071804
3           3  0.721555 -0.706771 -1.039575  0.271860
   Unnamed: 0         0         1         2         3
4           4 -0.424972  0.567020  0.276232 -1.087401
5           5 -0.673690  0.113648 -1.478427  0.524988
6           6  0.404705  0.577046 -1.715002 -1.039268
7           7 -0.370647 -1.157892 -1.344312  0.844885
   Unnamed: 0         0        1         2         3
8           8  1.075770 -0.10905  1.643563 -1.469388
9           9  0.357021 -0.67460 -1.776904 -0.968914

返回的reader是TextFileReader类型,它指向若干个chunk位置,只在访问数据的时候才真正把数据读入到内存。

这是一个可迭代的类型,采用for in的形式,即可逐个访问chunk。

每个chunk都是dataframe类型的。

 

 

还有一个邪教用法。

如果想跟数组一样,访问第i个chunk要怎么做?

使用 get_chunk(i)这个函数就可以了。

但是根据测试,get_chunk(i),在我这台机子上是固定10行为1个chunk,不受chunksize参数调整。

挺邪乎。

In [190]: reader = pd.read_csv('tmp.sv', sep='|', iterator=True)

In [191]: reader.get_chunk(5)
Out[191]: 
   Unnamed: 0         0         1         2         3
0           0  0.469112 -0.282863 -1.509059 -1.135632
1           1  1.212112 -0.173215  0.119209 -1.044236
2           2 -0.861849 -2.104569 -0.494929  1.071804
3           3  0.721555 -0.706771 -1.039575  0.271860
4           4 -0.424972  0.567020  0.276232 -1.087401

//官方地址:http://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io-chunking

 

实践手册

 

1.获取行数

count = 0
fp = open('totalExposureLog.out','r', encoding='utf-8')
while 1:
	buffer = fp.read(8*1024*1024)
	if not buffer:
		break
	count += buffer.count('\n')

print(count)
fp.close()


//https://blog.csdn.net/u012762054/article/details/78384294

这样你心里就有x数了,知道这个文件有多少行。

估算自己的内存大概撑得住多少行的数据,把原始数据划分为多少块比较合适。

例如我这个文件有102386695行,四舍五入1个亿。

大概划分成500万行,20个chunk就可以了。

 

2.使用chunk来read_csv

#1亿行,每500w为1个chunk
reader = pd.read_csv('totalExposureLog.out', sep='\t',chunksize=5000000)

for i,ck in enumerate(reader):
    print(i,' ',len(ck))
    ck.to_csv('../data/bb_'+str(i)+'.csv', index=False)

迭代访问即可。

 

3.合并表

使用pandas.concat

当axis = 0时,concat的效果是列对齐。

#我的数据分了21个chunk,标号是0~20
loader = [pd.read_csv('../data/bb_'+str(i)+'.csv') for i in range(21)]
pd.concat(loader, axis=0).reset_index(drop=True)

一般来说小水存是不可能把21个chunk都concat到一起的。

根据实际情况调整吧。

  • 20
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值