首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按列数将可变列行结构读入Pandas

按列数将可变列行结构读入Pandas
EN

Stack Overflow用户
提问于 2013-04-09 17:07:39
回答 2查看 1.7K关注 0票数 1

我需要从一个大文件中创建一个Pandas DataFrame,其中包含空格分隔值和取决于列数的行结构。

原始数据如下所示:

代码语言:javascript
复制
2008231.0 4891866.0 383842.0 2036693.0 4924388.0 375170.0

在一行或多行中,将忽略换行符。

如果列数为3,则最终结果如下:

代码语言:javascript
复制
[(u'2008231.0', u'4891866.0', u'383842.0'),
(u'2036693.0', u'4924388.0', u'375170.0')]

将文件拆分成行取决于文件的元部分中声明的列数。

目前,我将文件拆分成一个大列表,并将其拆分成行:

代码语言:javascript
复制
def grouper(n, iterable, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

(代码来自itertools示例)

问题是,我最终在内存中得到了数据的多个副本。对于500MB+文件,这会快速地消耗内存,而Pandas在读取这么大的MultiIndexes列表时会遇到一些问题。

如何将Pandas文件读取功能(read_csv、read_table、read_fwf)用于此类数据?

或者,有没有其他方法可以在没有辅助数据结构的情况下将数据读入Pandas?

EN

回答 2

Stack Overflow用户

发布于 2013-04-09 21:41:20

尽管可以创建自定义的类似文件的对象,但与pd.read_table的正常使用相比,这会非常慢

代码语言:javascript
复制
import pandas as pd
import re

filename = 'raw_data.csv'
class FileLike(file):
    """ Modeled after FileWrapper
    http://stackoverflow.com/a/14279543/190597 (Thorsten Kranz)
    """
    def __init__(self, *args):
        super(FileLike, self).__init__(*args)
        self.buffer = []
    def next(self):
        if not self.buffer:
            line = super(FileLike, self).next()
            self.buffer = re.findall(r'(\S+\s+\S+\s+\S+)', line)
        if self.buffer:
            line = self.buffer.pop()
            return line

with FileLike(filename, 'r') as f:
    df = pd.read_table(f, header=None, delimiter='\s+')
    print(len(df))

当我尝试在一个5.8M的文件(由200000行组成)上使用FileLike时,上面的代码需要3.9秒才能运行。

相反,如果我对数据进行预处理(将每行拆分为2行并将结果写入磁盘):

代码语言:javascript
复制
import fileinput
import sys
import re

filename = 'raw_data.csv'
for line in fileinput.input([filename], inplace = True, backup='.bak'):
    for part in re.findall(r'(\S+\s+\S+\s+\S+)', line):
        print(part)

然后,您当然可以使用pd.read_table正常地将数据加载到Pandas中

代码语言:javascript
复制
with open(filename, 'r') as f:
    df = pd.read_table(f, header=None, delimiter='\s+')
    print(len(df))

重写文件所需的时间约为0.6秒,现在加载DataFrame需要约0.7秒。

所以,你最好先把数据重写到磁盘上。

票数 1
EN

Stack Overflow用户

发布于 2013-04-09 18:29:55

我不认为有一种方法可以使用与列相同的分隔符来分隔行。

解决此问题的一种方法是在使用read_csv创建系列之后使用reshape (这很可能是一个拷贝而不是视图,以保持数据的连续性

代码语言:javascript
复制
s = pd.read_csv(file_name, lineterminator=' ', header=None)
df = pd.DataFrame(s.values.reshape(len(s)/n, n))

在您的示例中:

代码语言:javascript
复制
In [1]: s = pd.read_csv('raw_data.csv', lineterminator=' ', header=None, squeeze=True)

In [2]: s
Out[2]: 
0    2008231
1    4891866
2     383842
3    2036693
4    4924388
5     375170
Name: 0, dtype: float64

In [3]: pd.DataFrame(s.values.reshape(len(s)/3, 3))
Out[3]: 
         0        1       2
0  2008231  4891866  383842
1  2036693  4924388  375170
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15897805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档