Разредената рамка от данни на Pandas е по-голяма на диска от плътната версия

Намирам, че разредените версии на рамка от данни всъщност са много по-големи, когато се записват на диск, отколкото плътните версии. какво правя грешно

test = pd.DataFrame(ones((4,4000)))
test.ix[:,:] = nan
test.ix[0,0] = 47

test.to_hdf('test3', 'df')
test.to_sparse(fill_value=nan).to_hdf('test4', 'df')

test.to_pickle('test5')
test.to_sparse(fill_value=nan).to_pickle('test6')

....
ls -sh test*
200K test3   16M test4  164K test5  516K test6

Използване на версия 0.12.0

В крайна сметка бих искал ефективно да съхранявам 10^7 на 60 масива с около 10% плътност, след което да ги изтегля в кадри с данни на Pandas и да си играя с тях.


Редактиране: Благодаря на Джеф за отговора на оригиналния въпрос. Допълнителен въпрос: Изглежда, че това дава спестявания само за ецване, а не при използване на други формати като HDF5. Мариноването най-добрият ми път ли е?

print shape(array_activity) #This is just 0s and 1s
(1020000, 60)

test = pd.DataFrame(array_activity)
test_sparse = test.to_sparse()
print test_sparse.density
0.0832333496732

test.to_hdf('1', 'df')
test_sparse.to_hdf('2', 'df')
test.to_pickle('3')
test_sparse.to_pickle('4')
!ls -sh 1 2 3 4
477M 1  544M 2  477M 3   83M 4

Това са данни, които като списък с индекси в .mat файл на Matlab са по-малко от 12M. Бях нетърпелив да го прехвърля във формат HDF5/Pytables, за да мога да взема само конкретни индекси (други файлове са много по-големи и отнемат много повече време за зареждане в паметта) и след това лесно да правя Pandasy неща с тях. Може би не постъпвам по правилния начин?


person jeffalstott    schedule 06.02.2014    source източник
comment
добавете филтър за компресия, вижте тук: pandas.pydata.org/pandas- docs/dev/io.html#compression   -  person Jeff    schedule 07.02.2014
comment
С плътна рамка от данни и complevel=9 и complib='blosc', това ни сваля от 544M на 26M. Много по-добре, но все още не се справя с 12M. Опитът за компресиране с рядката рамка от данни извежда TypeError: TypeError: cannot properly create the storer for: [_TABLE_MAP] [group->/test_sparse (Group) '',value-><class 'pandas.sparse.frame.SparseDataFrame'>,table->True,append->True,kwargs->{'encoding': None}]   -  person jeffalstott    schedule 07.02.2014
comment
хм.... това не е правилният формат; трябва да го запише с table=False; но това също е по подразбиране. нека да погледна.   -  person Jeff    schedule 07.02.2014
comment
можете ли да публикувате рамката, която сте запазили (в плътен формат е добре), компресиран pls! на да кажем връзка към dropbox?   -  person Jeff    schedule 07.02.2014
comment
Ето ви: dropbox.com/s/d374qoxeua5n3gn/store_compressed.h5   -  person jeffalstott    schedule 07.02.2014


Отговори (1)


вие създавате рамка, която има 4000 колони и само 4 реда; sparse се обработва по редове, така че обърнете размерите.

In [2]: from numpy import *

In [3]: test = pd.DataFrame(ones((4000,4)))

In [4]: test.ix[:,:] = nan

In [5]: test.ix[0,0] = 47

In [6]: test.to_hdf('test3', 'df')

In [7]: test.to_sparse(fill_value=nan).to_hdf('test4', 'df')

In [8]: test.to_pickle('test5')

In [9]: test.to_sparse(fill_value=nan).to_pickle('test6')

In [11]: !ls -sh test3 test4 test5 test6
164K test3  148K test4  160K test5   36K test6

Последващи действия. Вашият магазин, който предоставихте, беше написан във формат table и в резултат на това запази плътната версия (Sparse не се поддържа за табличен формат, който е много гъвкав и подлежи на заявки, вижте документи.

Освен това може да искате да експериментирате със запазването на вашия файл, като използвате 2 различни представяния на разредения формат.

така че ето примерна сесия:

df = 
In [1]: df = pd.read_hdf('store_compressed.h5','test')

In [2]: type(df)
Out[2]: pandas.core.frame.DataFrame

In [3]: df.to_sparse(kind='block').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [4]: df.to_sparse(kind='integer').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [5]: df.to_sparse(kind='block').to_hdf('test_block.h5','test',mode='w',complib='blosc',complevel=9)

In [6]: df.to_sparse(kind='integer').to_hdf('test_integer.h5','test',mode='w',complib='blosc',complevel=9)

In [7]: df.to_hdf('test_dense_fixed.h5','test',mode='w',complib='blosc',complevel=9)

In [8]: df.to_hdf('test_dense_table.h5','test',mode='w',format='table',complib='blosc',complevel=9)

In [9]: !ls -ltr *.h5
-rwxrwxr-x 1 jreback users 57015522 Feb  6 18:19 store_compressed.h5
-rw-rw-r-- 1 jreback users 30335044 Feb  6 19:01 test_block.h5
-rw-rw-r-- 1 jreback users 28547220 Feb  6 19:02 test_integer.h5
-rw-rw-r-- 1 jreback users 44540381 Feb  6 19:02 test_dense_fixed.h5
-rw-rw-r-- 1 jreback users 57744418 Feb  6 19:03 test_dense_table.h5

IIRC е грешка в 0.12, тъй като to_hdf не предава всички аргументи, така че вероятно искате да използвате:

with get_store('test.h5',mode='w',complib='blosc',complevel=9) as store:
    store.put('test',df)

Те се съхраняват основно като колекция от SparseSeries, така че ако плътността е ниска и несъседна, тогава няма да е толкова минимална, що се отнася до размера. Разреденият пакет на Pandas се справя по-добре с по-малък брой съседни блокове, въпреки че YMMV. scipy предоставя и някои оскъдни инструменти за обработка.

Въпреки че IMHO това са доста тривиални размери за HDF5 файлове така или иначе, можете да се справите с гигантски брой редове; и файлове с размери от 10 до 100 гигабайта могат лесно да се обработват (макар и препоръчително).

Освен това можете да обмислите използването на табличен формат, ако това наистина е справочна таблица, както можете да направите заявка.

person Jeff    schedule 06.02.2014