MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Големи работни потоци от данни с помощта на панди

Рутинно използвам десетки гигабайта данни само в тази мода. Имам таблици на диска, които чета чрез заявки, създавам данни и добавям обратно.

Струва си да прочетете документите и по-късно в тази тема за няколко предложения как да съхранявате данните си.

Подробности, които ще повлияят на това как съхранявате данните си, като:
Дайте колкото можете повече подробности; и мога да ви помогна да разработите структура.

  1. Размер на данните, брой редове, колони, типове колони; добавяте ли редове или само колони?
  2. Как ще изглеждат типичните операции. напр. направете заявка за колони, за да изберете куп редове и конкретни колони, след това направете операция (в паметта), създайте нови колони, запазете ги.
    (Даването на пример за играчка може да ни позволи да предложим по-конкретни препоръки. )
  3. След тази обработка какво правите? Стъпка 2 ad hoc ли е или повтаряема?
  4. Входни плоски файлове:колко, приблизителен общ размер в Gb. Как са организирани тези напр. по записи? Всяко от тях съдържа ли различни полета или има записи на файл с всички полета във всеки файл?
  5. Избирали ли сте някога подмножества от редове (записи) въз основа на критерии (например избирате редовете с поле A> 5)? и след това направете нещо или просто изберете полета A, B, C с всички записи (и след това направите нещо)?
  6. Работите ли върху всичките си колони (в групи) или има ли добра част, която може да използвате само за отчети (напр. искате да запазите данните наоколо, но не е необходимо да ги изтегляте яснота на колоната до момента на окончателните резултати)?

Решение

Уверете се, че имате панди поне 0.10.1 инсталиран.

Четете итериращите файлове парче по парче и множество заявки за таблици.

Тъй като pytables е оптимизиран да работи по редове (което е това, към което правите заявка), ние ще създадем таблица за всяка група полета. По този начин е лесно да изберете малка група от полета (която ще работи с голяма таблица, но е по-ефективно да го направите по този начин... Мисля, че може да успея да коригирам това ограничение в бъдеще... това е все пак по-интуитивен):
(По-долу е псевдокод.)

import numpy as np
import pandas as pd

# create a store
store = pd.HDFStore('mystore.h5')

# this is the key to your storage:
#    this maps your fields to a specific group, and defines 
#    what you want to have as data_columns.
#    you might want to create a nice class wrapping this
#    (as you will want to have this map and its inversion)  
group_map = dict(
    A = dict(fields = ['field_1','field_2',.....], dc = ['field_1',....,'field_5']),
    B = dict(fields = ['field_10',......        ], dc = ['field_10']),
    .....
    REPORTING_ONLY = dict(fields = ['field_1000','field_1001',...], dc = []),

)

group_map_inverted = dict()
for g, v in group_map.items():
    group_map_inverted.update(dict([ (f,g) for f in v['fields'] ]))

Четене на файловете и създаване на хранилището (по същество прави това, което append_to_multiple прави):

for f in files:
   # read in the file, additional options may be necessary here
   # the chunksize is not strictly necessary, you may be able to slurp each 
   # file into memory in which case just eliminate this part of the loop 
   # (you can also change chunksize if necessary)
   for chunk in pd.read_table(f, chunksize=50000):
       # we are going to append to each table by group
       # we are not going to create indexes at this time
       # but we *ARE* going to create (some) data_columns

       # figure out the field groupings
       for g, v in group_map.items():
             # create the frame for this group
             frame = chunk.reindex(columns = v['fields'], copy = False)    

             # append it
             store.append(g, frame, index=False, data_columns = v['dc'])

Сега имате всички таблици във файла (всъщност бихте могли да ги съхранявате в отделни файлове, ако желаете, вероятно ще трябва да добавите името на файла към group_map, но вероятно това не е необходимо).

Ето как получавате колони и създавате нови:

frame = store.select(group_that_I_want)
# you can optionally specify:
# columns = a list of the columns IN THAT GROUP (if you wanted to
#     select only say 3 out of the 20 columns in this sub-table)
# and a where clause if you want a subset of the rows

# do calculations on this frame
new_frame = cool_function_on_frame(frame)

# to 'add columns', create a new group (you probably want to
# limit the columns in this new_group to be only NEW ones
# (e.g. so you don't overlap from the other tables)
# add this info to the group_map
store.append(new_group, new_frame.reindex(columns = new_columns_created, copy = False), data_columns = new_columns_created)

Когато сте готови за post_processing:

# This may be a bit tricky; and depends what you are actually doing.
# I may need to modify this function to be a bit more general:
report_data = store.select_as_multiple([groups_1,groups_2,.....], where =['field_1>0', 'field_1000=foo'], selector = group_1)

Що се отнася до колоните_данни, всъщност не е необходимо да дефинирате НЯКОЙ колони_данни; те ви позволяват да избирате подизбор на редове въз основа на колоната. напр. нещо като:

store.select(group, where = ['field_1000=foo', 'field_1001>0'])

Те може да са най-интересни за вас на етапа на окончателното генериране на отчет (по същество колона с данни е отделена от други колони, което може да повлияе донякъде на ефективността, ако дефинирате много).

Може също така да:

  • създайте функция, която взема списък с полета, търси групите в group_map, след което ги избира и конкатенира резултатите, така че да получите резултантната рамка (това по същество прави select_as_multiple). По този начин структурата ще бъде доста прозрачна за вас.
  • индексира определени колони с данни (прави поднабора на редове много по-бърз).
  • активиране на компресията.

Кажете ми, когато имате въпроси!



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как мога да деактивирам съобщенията в журнала на MongoDB в конзолата?

  2. Как да обедините документи при импортиране на файл в MongoDB

  3. Как да направите заявка за is not null в Mongo?

  4. Извършване на заявки за регулярни изрази с PyMongo

  5. преброяване на масиви във всички документи с mongo