Pandas.read_csv из строки или данных пакета
У меня есть некоторые текстовые данные csv в пакете, который я хочу прочитать, используя read_csv. Я делал это с помощью
from pkgutil import get_data
from StringIO import StringIO
data = read_csv(StringIO(get_data('package.subpackage', 'path/to/data.csv')))
Однако StringIO.StringIO исчезает в Python 3, а io.StringIO принимает только Unicode. Есть ли простой способ сделать это?
Изменить: ниже не работает
import pandas as pd
import pkgutil
from io import StringIO
def get_data_file(pkg, path):
f = StringIO()
contents = unicode(pkgutil.get_data('pymc.examples', 'data/wells.dat'))
f.write(contents)
return f
wells = get_data_file('pymc.examples', 'data/wells.dat')
data = pd.read_csv(wells, delimiter=' ', index_col='id',
dtype={'switch': np.int8})
с ошибкой
File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 401, in parser_f
return _read(filepath_or_buffer, kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 209, in _read
parser = TextFileReader(filepath_or_buffer, **kwds)
File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 509, in __init__
self._make_engine(self.engine)
File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 611, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
File "/usr/local/lib/python2.7/dist-packages/pandas/io/parsers.py", line 893, in __init__
self._reader = _parser.TextReader(src, **kwds)
File "parser.pyx", line 441, in pandas._parser.TextReader.__cinit__ (pandas/src/parser.c:3940)
File "parser.pyx", line 551, in pandas._parser.TextReader._get_header (pandas/src/parser.c:5096)
pandas._parser.CParserError: Passed header=0 but only 0 lines in file
Ответы
Ответ 1
Следующее работало для меня в версии 3.3:
>>> import numpy as np, pandas as pd
>>> import io, pkgutil
>>> wells = pkgutil.get_data('pymc.examples', 'data/wells.dat')
>>> type(wells)
<class 'bytes'>
>>> df = pd.read_csv(io.BytesIO(wells), encoding='utf8', sep=" ", index_col="id", dtype={"switch": np.int8})
>>> df.head()
switch arsenic dist assoc educ
id
1 1 2.36 16.826000 0 0
2 1 0.71 47.321999 0 0
3 0 2.07 20.966999 0 10
4 1 1.15 21.486000 0 12
5 1 1.10 40.874001 1 14
[5 rows x 5 columns]
N.B. Мне пришлось вручную помещать wells.dat
в это место, поэтому я не могу поклясться, что скопировал его правильно и что нет конечных пробелов, потому что я их удалил. Но передавая объект read_csv
a BytesIO
, и параметр кодирования должен работать. (На самом деле, вы, вероятно, можете обойтись без него, но это хорошая привычка. io.TextIOWrapper
может быть другим вариантом.)
Ответ 2
Чтобы передать функцию string
в pandas read_csv
, вы можете использовать io.StringIO
, т.е.:
import pandas as pd
from io import StringIO
df = pd.read_csv(StringIO("csv string..."))