2016-06-27 3 views
1

Я использую numpy.fromfile построить массив, который я могу передать в pandas.DataFrame конструкторNumPy: FromFile для сжатых файлов

import numpy as np 
import pandas as pd 

def read_best_file(file, **kwargs): 
    ''' 
    Loads best price data into a dataframe 
    ''' 
    names = [ 'time', 'bid_size', 'bid_price', 'ask_size', 'ask_price' ] 
    formats = [ 'u8', 'i4',  'f8',  'i4',  'f8'  ] 
    offsets = [ 0,  8,   12,   20,   24   ] 

    dt = np.dtype({ 
      'names': names, 
      'formats': formats, 
      'offsets': offsets 
     }) 
    return pd.DataFrame(np.fromfile(file, dt)) 

Я хотел бы продлить этот метод для работы с файлами с gzip'нутыми.

Согласно документации numpy.fromfile, первый параметр файла:

file : file or str 
Open file object or filename 

Таким образом, я добавил следующее, чтобы проверить на GZIP путь к файлу:

if isinstance(file, str) and file.endswith(".gz"): 
    file = gzip.open(file, "r") 

Однако, когда я пытаюсь передайте это через конструктор fromfile. Я получаю IOError:

IOError: first argument must be an open file

Вопрос:

Как я могу позвонить numpy.fromfile с сжатыми файлами?

Edit:

По запросу в комментариях, показывая выполнение которых проверяет наличие файлов с gzip'нутыми:

def read_best_file(file, **kwargs): 
    ''' 
    Loads best price data into a dataframe 
    ''' 
    names = [ 'time', 'bid_size', 'bid_price', 'ask_size', 'ask_price' ] 
    formats = [ 'u8', 'i4',  'f8',  'i4',  'f8'  ] 
    offsets = [ 0,  8,   12,   20,   24   ] 

    dt = np.dtype({ 
      'names': names, 
      'formats': formats, 
      'offsets': offsets 
     }) 

    if isinstance(file, str) and file.endswith(".gz"): 
     file = gzip.open(file, "r") 

    return pd.DataFrame(np.fromfile(file, dt)) 
+0

Мы должны были бы увидеть, как именно осуществляется проверка. – TheBlackCat

+0

@TheBlackCat Буквально перед оператором возврата эти две строки вставлены. –

+0

Можете ли вы показать полный код с правильным отступом? – TheBlackCat

ответ

2

open.gzip() не возвращает истинный file объект. Это утка одна .. она ходит как утка, звучит как утка, но не совсем утка за numpy. Так numpy является весьма строгим (так много написано в коде ниже уровня C, может потребоваться фактический дескриптор файла.)

Вы можете получить основной file от gzip.open() вызова, но это только собирается получить вам сжатый поток ,

Это то, что я сделал бы: я бы использовал subprocess.Popen(), чтобы вызвать zcat, чтобы распаковать файл в виде потока.

>>> import subprocess 
>>> p = subprocess.Popen(["/usr/bin/zcat", "foo.txt.gz"], stdout=subprocess.PIPE) 
>>> type(p.stdout) 
<type 'file'> 
>>> p.stdout.read() 
'hello world\n' 

Теперь вы можете передать p.stdout как file объекта numpy:

np.fromfile(p.stdout, ...) 
+0

'fromfile' делает свой собственный файл, читаемый в c-коде. Он не импортирует и не использует модуль 'gzip'. – hpaulj

+0

Это не работает (для меня), потому что труба, которую записывает stdout zcat, не доступна для поиска. Поэтому np.fromfile вызывает «IOError: не удалось найти в файле» – rodion

+0

Ах, тогда вам придется либо использовать временный файл, либо строку string, если ваш файл будет вписываться в память. Более подробно обсуждение отсутствия произвольного доступа gzip обсуждается здесь: http://stackoverflow.com/questions/25985645/about-the-use-of-seek-on-gzip-files – rrauenza

Смежные вопросы