"Duże przepływy danych" za pomocą pand

Przez wiele miesięcy ucząc się pand starałem się znaleźć odpowiedź na to pytanie. Używam SAS do mojej codziennej pracy i jest to świetne, ponieważ jest to wsparcie poza rdzeniem. Jednak SAS jest okropny jako oprogramowanie z wielu innych powodów.

Pewnego dnia mam nadzieję zastąpić SAS Pythonem i pandami, ale obecnie brakuje mi out-of-core workflow dla dużych zbiorów danych. Nie mówię o "big data", który wymaga rozproszonej sieci, ale raczej pliki zbyt duże, aby zmieścić się w pamięci, ale wystarczająco małe, aby zmieścić się na dysku twardym.

Moją pierwszą myślą jest użycie HDFStore do przechowywania dużych zbiorów danych na dysku i pobierania tylko potrzebnych elementów do ramek danych do analizy. Inni wymienili MongoDB jako łatwiejszą w użyciu alternatywę. Moje pytanie Jest Takie:

Jakie są przepływy najlepszych praktyk w celu osiągnięcia:

  1. ładowanie plików płaskich do stałej, na dysku struktury bazy danych
  2. odpytywanie bazy danych aby pobrać dane do zasilania w strukturę danych pandy
  3. Aktualizacja bazy danych po manipulowaniu elementami w pandach
[2]}Przykłady z prawdziwego świata byłyby bardzo mile widziane, zwłaszcza od każdego, kto używa pand na "dużych danych".

Edit -- przykład jak chciałbym aby to działało:

  1. iteracyjnie Importuj duży plik płaski i przechowuj go w stałej, dyskowej strukturze bazy danych. Pliki te są zazwyczaj zbyt duże, aby zmieścić się w pamięci.
  2. w kolejności aby użyć Pandy, chciałbym przeczytać podzbiory tych danych (zwykle tylko kilka kolumn na raz), które mogą zmieścić się w pamięci.
  3. tworzyłbym nowe kolumny, wykonując różne operacje na wybranych kolumnach.
  4. będę musiał dodać te nowe kolumny do struktury bazy danych.
Staram się znaleźć najlepszy sposób na wykonanie tych kroków. Czytając linki o pandach i pytablach wydaje się, że dodanie nowej kolumny może być problem.

Edit -- odpowiadając na pytania Jeffa konkretnie:

    Buduję modele ryzyka kredytowego. Rodzaje danych obejmują charakterystykę telefonu, SSN i adresu; wartości nieruchomości; informacje obraźliwe, takie jak rejestry kryminalne, bankructwa itp... Zbiory danych, z których korzystam na co dzień, mają średnio od 1000 do 2000 pól mieszanych typów danych: zmiennych ciągłych, nominalnych i porządkowych zarówno liczbowych, jak i znakowych. Rzadko dołączam wiersze, ale wykonuję wiele operacji, które tworzą nowe kolumny.
  1. Typowe operacje polegają na łączeniu kilku kolumn za pomocą logiki warunkowej w nową kolumnę złożoną. Na przykład if var1 > 2 then newvar = 'A' elif var2 = 4 then newvar = 'B'. Wynikiem tych operacji jest nowa kolumna dla każdego rekordu w moim zbiorze danych.
  2. na koniec chciałbym dodać te nowe kolumny do struktury danych na dysku. Powtórzyłbym Krok 2, eksplorując dane za pomocą krzyżyków i statystyk opisowych próbując znaleźć ciekawe, intuicyjne relacje do model.
  3. typowy plik projektu ma zwykle około 1GB. Pliki są zorganizowane w taki sposób, że wiersz składa się z rekordu danych konsumenta. Każdy wiersz ma taką samą liczbę kolumn dla każdego rekordu. Tak będzie zawsze.
  4. to dość rzadkie, że podzbiór wierszy podczas tworzenia nowej kolumny. Jednak dość często zdarza mi się podzestawiać wiersze podczas tworzenia raportów lub generowania statystyk opisowych. Na przykład, mogę chcieć stworzyć prosty częstotliwość dla konkretnej branży, powiedzmy detalicznych kart kredytowych. Aby to zrobić, wybrałbym tylko te rekordy, w których linia biznesowa = retail oprócz kolumn, na których chcę raportować. Podczas tworzenia nowych kolumn, jednak, chciałbym wyciągnąć wszystkie wiersze danych i tylko kolumny potrzebne do operacji.
  5. proces modelowania wymaga, aby analizować każdą kolumnę, szukać interesujących relacji z jakąś zmienną wynikową i tworzyć nowe kolumny złożone, które opisz te relacje. Kolumny, które badam, są zwykle wykonywane w małych zestawach. Na przykład skupię się na zestawie powiedzmy 20 kolumn zajmujących się tylko wartościami nieruchomości i obserwuję, jak odnoszą się one do niewywiązania się z kredytu. Po ich zbadaniu i stworzeniu nowych kolumn, przechodzę do innej grupy kolumn, powiedzmy, Edukacja college ' u i powtarzam proces. To, co robię, to tworzenie zmiennych kandydata, które wyjaśniają związek między moimi danymi a pewnym wynikiem. Na na samym końcu tego procesu stosuję kilka technik uczenia się, które tworzą równanie z tych kolumn złożonych.

Rzadko zdarza mi się dodawać wiersze do zbioru danych. Prawie zawsze będę tworzyć nowe kolumny(zmienne lub funkcje w statystyce/uczeniu maszynowym).

Author: Acumenus, 2013-01-10

16 answers

Rutynowo używam dziesiątek gigabajtów danych w taki właśnie sposób np. mam na dysku tabele, które czytam za pomocą zapytań, tworzę Dane i dołączam z powrotem.

Warto przeczytać dokumenty i pod koniec tego wątku kilka sugestii, jak przechowywać dane.

Szczegóły, które będą miały wpływ na sposób przechowywania danych, jak:
podaj jak najwięcej szczegółów, a ja pomogę ci opracować strukturę.

  1. Rozmiar danych, # wierszy, kolumny, rodzaje kolumn; czy dodajesz wiersze, czy tylko kolumny?
  2. jak będą wyglądać typowe operacje. Np. wykonaj Zapytanie o kolumny, aby wybrać kilka wierszy i konkretnych kolumn, a następnie wykonaj operację( w pamięci), utwórz nowe kolumny, zapisz je.
    (Podanie przykładu z zabawką może umożliwić nam przedstawienie bardziej szczegółowych zaleceń.)
  3. po tym przetwarzaniu, to co robisz? Czy Krok 2 jest ad hoc, czy powtarzalny?
  4. Input flat files: how many, rough total size in Gb. Jak są one organizowane np. przez płyty? Czy każdy z nich zawiera inne pola, czy też mają jakieś rekordy w pliku ze wszystkimi polami w każdym pliku?
  5. Czy kiedykolwiek wybierasz podzbiory wierszy (rekordów) na podstawie kryteriów (np. wybierz wiersze z polem a > 5)? a potem coś zrobić, czy po prostu wybrać pola A, B, C ze wszystkimi rekordami(a potem coś zrobić)?
  6. czy "pracujesz" na wszystkich swoich kolumnach (w grupach), czy są tam dobre proporcje, które można tylko użyj do raportów(np. chcesz zachować dane, ale nie musisz ciągnąć tej kolumny do czasu ostatecznych wyników)?

Rozwiązanie

upewnij się, że masz pandy przynajmniej 0.10.1 zainstalowany.

Odczytuje iterację plików fragment po kawałku i wiele zapytań tabel.

Ponieważ pytables jest zoptymalizowany pod kątem operowania na wierszach (co jest tym, co zapytasz), utworzymy tabelę dla każdej grupy pól. Tędy. łatwo wybrać małą grupę pól (która będzie działać z dużą tabelą, ale bardziej wydajne jest to zrobić w ten sposób... Myślę, że będę w stanie naprawić to ograniczenie w przyszłości... tak czy inaczej jest to bardziej intuicyjne):
(Poniżej znajduje się pseudokod.)

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'] ]))

Czytanie w plikach i tworzenie magazynu (zasadniczo robienie tego, co robi 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'])

Teraz masz wszystkie tabele w pliku (właściwie możesz je przechowywać w osobnych plikach, jeśli chcesz, musisz Dodaj nazwę pliku do group_map, ale prawdopodobnie nie jest to konieczne).

W ten sposób otrzymujesz kolumny i tworzysz nowe:

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)

Kiedy będziesz gotowy na 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)

Jeśli chodzi o data_columns, nie musisz definiować żadnych data_columns; pozwalają one na podwajanie wierszy na podstawie kolumny. Np. coś w stylu:

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

Mogą być najbardziej interesujące dla Ciebie na etapie generowania raportu końcowego (zasadniczo kolumna danych jest segregowana z innych kolumn, co może nieco wpłynąć na efektywność, jeśli zdefiniujesz dużo).

Możesz też chcieć:

  • Utwórz funkcję, która pobiera listę pól, wyszukuje grupy w groups_map, następnie wybiera te i łączy wyniki, aby uzyskać wynikową ramkę(tak robi select_as_multiple). w ten sposób struktura będzie dość przejrzysta dla Ciebie.
  • indeksy na niektórych kolumnach danych (sprawia, że wiersz-podzbiór znacznie szybciej).
  • włącz kompresję.

Daj mi znać, gdy masz pytania!

 664
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-11 20:29:47

Myślę, że w powyższych odpowiedziach brakuje prostego podejścia, które uznałem za bardzo przydatne.

Gdy mam plik, który jest zbyt duży, aby załadować go do pamięci, dzielę plik na wiele mniejszych plików (albo przez wiersz lub cols)

Przykład: w przypadku 30-dniowego handlu danymi o rozmiarze ~30GB, rozkładam je na plik dziennie o rozmiarze ~1GB. Następnie przetwarzam każdy plik osobno i agreguję wyniki na końcu

Jedną z największych zalet jest to, że umożliwia równoległe przetwarzanie plików (wiele wątków lub procesów)

Inną zaletą jest to, że manipulowanie plikami (jak dodawanie/usuwanie dat w przykładzie) może być wykonywane przez zwykłe polecenia powłoki, co nie jest możliwe w bardziej zaawansowanych/skomplikowanych formatach plików

To podejście nie obejmuje wszystkich scenariuszy, ale jest bardzo przydatne w wielu z nich

 152
Author: user1827356,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-23 15:21:27

Jest teraz, dwa lata po pytaniu, "poza rdzeniem" pandy odpowiednik: dask . To jest doskonałe! Chociaż nie obsługuje wszystkich funkcjonalności pand, możesz zajść naprawdę daleko. Aktualizacja: w ciągu ostatnich dwóch lat został on konsekwentnie utrzymywany i istnieje znaczna społeczność użytkowników pracujących z Dask.

A teraz, cztery lata po pytaniu, pojawia się kolejny wysokowydajny odpowiednik "Out-of-core" w Vaex . "Wykorzystuje mapowanie pamięci, zero Polityka kopiowania pamięci i leniwe obliczenia dla najlepszej wydajności (brak marnowania pamięci)."Może obsługiwać zbiory danych o miliardach wierszy i nie zapisuje ich w pamięci (co umożliwia nawet analizę na nieoptymalnym sprzęcie).

 91
Author: Private,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-25 19:57:57

Jeśli Twoje zestawy danych mają od 1 do 20 GB, powinieneś otrzymać stację roboczą z 48 GB PAMIĘCI RAM. Wtedy Pandy mogą trzymać cały zestaw danych w pamięci RAM. Wiem, że nie jest to odpowiedź, której szukasz tutaj, ale robienie obliczeń naukowych na notebooku z 4GB PAMIĘCI RAM nie jest rozsądne.

 67
Author: rjurney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-02 07:14:07

Wiem, że to stary wątek, ale myślę, że biblioteka Blaze jest warta sprawdzenia. Jest stworzony do tego typu sytuacji.

Z docs:

Blaze rozszerza użyteczność NumPy i pandy na komputery rozproszone i poza rdzeniem. Blaze zapewnia interfejs podobny do interfejsu NumPy ND-Array lub Panda DataFrame, ale mapuje te znane interfejsy na wiele innych silników obliczeniowych, takich jak Postgres lub Spark.

Edit: Nawiasem mówiąc, jest wspierany przez ContinuumIO i Travisa Oliphanta, autora NumPy.

 63
Author: chishaku,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 22:09:40

Tak jest w przypadku pymongo. Mam również prototypów przy użyciu SQL server, SQLite, HDF, ORM (SQLAlchemy) w Pythonie. Pymongo jest przede wszystkim dokumentem bazującym na DB, więc każda osoba byłaby dokumentem (dict atrybutów). Wiele osób tworzy kolekcję i możesz mieć wiele kolekcji (ludzie, Giełda, dochód).

Pd.dateframe - > pymongo Uwaga: używam chunksize in read_csv, aby utrzymać go do 5 do 10K rekordów (pymongo zrzuca Gniazdo, jeśli jest większe)

aCollection.insert((a[1].to_dict() for a in df.iterrows()))

Querying: gt = większe niż...

pd.DataFrame(list(mongoCollection.find({'anAttribute':{'$gt':2887000, '$lt':2889000}})))

.find() zwraca iterator, więc często używam ichunked do siekania na mniejsze Iteratory.

A co powiesz na join skoro normalnie dostaję 10 źródeł danych do wklejenia razem:

aJoinDF = pandas.DataFrame(list(mongoCollection.find({'anAttribute':{'$in':Att_Keys}})))

Następnie (w moim przypadku czasami muszę się agg na aJoinDF najpierw przed jego "mergeable".)

df = pandas.merge(df, aJoinDF, on=aKey, how='left')

A następnie możesz zapisać nowe informacje do swojej głównej kolekcji za pomocą metody aktualizacji poniżej. (zbiór logiczny a fizyczne źródła danych).

collection.update({primarykey:foo},{key:change})

Na mniejszych Szukaj, po prostu denormalizuj. Na przykład, masz kod w dokumencie i po prostu dodaj tekst kodu pola i wykonaj wyszukiwanie dict podczas tworzenia dokumentów.

Teraz masz ładny zbiór danych oparty na osobie, możesz uwolnić swoją logikę na każdym przypadku i zrobić więcej atrybutów. Wreszcie można odczytać w pandy swoje 3 do pamięci max kluczowych wskaźników i zrobić pivots / agg / eksploracji danych. Działa mi to na 3 miliony rekordów z numerami / dużym tekstem/kategoriami/kodami/pływakami/...

Ty może również używać dwóch metod wbudowanych w MongoDB (MapReduce i aggregate framework). zobacz tutaj, aby uzyskać więcej informacji o frameworku agregatowym , ponieważ wydaje się być łatwiejszy niż MapReduce i wygląda przydatnie do szybkiej pracy agregatowej. Zauważ, że nie musiałem definiować moich pól ani relacji i mogę dodawać elementy do dokumentu. W obecnym stanie szybko zmieniającego się zestawu narzędzi numpy, pandas, python, MongoDB pomaga mi po prostu dostać się do pracy:) {]}

 55
Author: brian_the_bungler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-14 13:50:41

Jeden trik, który znalazłem pomocne dla dużych danych przypadków użycia jest zmniejszenie objętości danych poprzez zmniejszenie precyzji float do 32-bitowych. Nie ma to zastosowania we wszystkich przypadkach, ale w wielu aplikacjach 64-bitowa precyzja to przesada i warto mieć 2x oszczędności pamięci. Aby jeszcze bardziej oczywista sprawa:

>>> df = pd.DataFrame(np.random.randn(int(1e8), 5))
>>> df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000000 entries, 0 to 99999999
Data columns (total 5 columns):
...
dtypes: float64(5)
memory usage: 3.7 GB

>>> df.astype(np.float32).info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 100000000 entries, 0 to 99999999
Data columns (total 5 columns):
...
dtypes: float32(5)
memory usage: 1.9 GB
 49
Author: ytsaig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-03 06:51:24

Zauważyłem to trochę późno, ale pracuję z podobnym problemem(modele przedpłat hipotecznych). Moim rozwiązaniem było pominięcie warstwy Pandy HDFStore i użycie prostych pytabli. Zapisuję każdą kolumnę jako pojedynczą tablicę HDF5 w moim ostatecznym pliku.

Mój podstawowy obieg pracy polega na pobraniu pliku CSV z bazy danych. I gzip to, więc nie jest tak ogromny. Następnie konwertuję to do pliku HDF5 zorientowanego na wiersz, iterując go w Pythonie, konwertując każdy wiersz na prawdziwy typ danych i zapisując go do Plik HDF5. Zajmuje to kilkadziesiąt minut, ale nie używa żadnej pamięci, ponieważ działa tylko wiersz po wierszu. Następnie "transponuję" plik HDF5 zorientowany wierszem do pliku HDF5 zorientowanego kolumną.

Tabela wygląda następująco:

def transpose_table(h_in, table_path, h_out, group_name="data", group_path="/"):
    # Get a reference to the input data.
    tb = h_in.getNode(table_path)
    # Create the output group to hold the columns.
    grp = h_out.createGroup(group_path, group_name, filters=tables.Filters(complevel=1))
    for col_name in tb.colnames:
        logger.debug("Processing %s", col_name)
        # Get the data.
        col_data = tb.col(col_name)
        # Create the output array.
        arr = h_out.createCArray(grp,
                                 col_name,
                                 tables.Atom.from_dtype(col_data.dtype),
                                 col_data.shape)
        # Store the data.
        arr[:] = col_data
    h_out.flush()

Odczytanie tego z powrotem wygląda następująco:

def read_hdf5(hdf5_path, group_path="/data", columns=None):
    """Read a transposed data set from a HDF5 file."""
    if isinstance(hdf5_path, tables.file.File):
        hf = hdf5_path
    else:
        hf = tables.openFile(hdf5_path)

    grp = hf.getNode(group_path)
    if columns is None:
        data = [(child.name, child[:]) for child in grp]
    else:
        data = [(child.name, child[:]) for child in grp if child.name in columns]

    # Convert any float32 columns to float64 for processing.
    for i in range(len(data)):
        name, vec = data[i]
        if vec.dtype == np.float32:
            data[i] = (name, vec.astype(np.float64))

    if not isinstance(hdf5_path, tables.file.File):
        hf.close()
    return pd.DataFrame.from_items(data)
Zazwyczaj uruchamiam to na komputerze z dużą ilością pamięci, więc mogę nie być wystarczająco ostrożny z moim zużyciem pamięci. Na przykład domyślnie operacja load odczytuje całe dane gotowi.

To ogólnie działa dla mnie, ale jest trochę niezgrabne, i nie mogę użyć fantazyjnej magii pytables.

Edit: prawdziwą zaletą tego podejścia, nad domyślną tablicą rekordów, jest to, że mogę następnie załadować dane do R za pomocą h5r, który nie radzi sobie z tabelami. A przynajmniej nie byłem w stanie załadować heterogenicznych tabel.

 47
Author: Johann Hibschman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 15:38:07

Jak zauważyli inni, po kilku latach pojawił się odpowiednik "Out-of-core" pand: dask . Mimo że dask nie jest zamiennikiem pand i cała jego funkcjonalność wyróżnia się z kilku powodów:]}

Dask jest elastyczną biblioteką obliczeń równoległych do obliczeń analitycznych, która jest zoptymalizowana pod kątem dynamicznego harmonogramowania zadań dla interaktywnych obciążeń obliczeniowych Zbiory "Big Data", takie jak tablice równoległe, ramki danych i listy, które rozszerzają wspólne interfejsy, takie jak Iteratory NumPy, Pandas lub Python do środowisk większych niż pamięć lub rozproszonych i skalują się od laptopów do klastrów.

Dask podkreśla następujące cnoty:

  • Familiar: dostarcza paralelized numpy array i pandy DataFrame obiektów
  • Elastyczny: zapewnia interfejs harmonogramowania zadań dla większej liczby niestandardowych obciążeń i integracji z innymi projektami.
  • natywny: umożliwia przetwarzanie rozproszone w czystym Pythonie z dostępem do Pydata stack.
  • Fast: działa z niskim obciążeniem, małym opóźnieniem i minimalną serializacją niezbędną dla szybkich algorytmów numerycznych]}
  • skalowalne: działa stabilnie na klastrach z 1000 rdzeniami skalowane w dół: trywialne jest skonfigurowanie i uruchomienie na laptopie w jednym procesie
  • Responsywny: zaprojektowany z myślą o interaktywnych komputerach, zapewnia szybkie informacje zwrotne i diagnostykę, aby pomóc ludziom]}

I dodać prosty kod próbka:

import dask.dataframe as dd
df = dd.read_csv('2015-*-*.csv')
df.groupby(df.user_id).value.mean().compute()

Zastępuje jakiś kod pandy taki:

import pandas as pd
df = pd.read_csv('2015-01-01.csv')
df.groupby(df.user_id).value.mean()

I, szczególnie godne uwagi, zapewnia poprzez interfejs concurrent.futures ogólną infrastrukturę do składania zadań niestandardowych:

from dask.distributed import Client
client = Client('scheduler:port')

futures = []
for fn in filenames:
    future = client.submit(load, fn)
    futures.append(future)

summary = client.submit(summarize, futures)
summary.result()
 36
Author: wp78de,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-08 17:07:24

Warto tutaj wspomnieć Ray jak również
jest to rozproszony framework obliczeniowy, który posiada własną implementację dla pand w sposób rozproszony.

Wystarczy wymienić import pandas, a kod powinien działać tak jak jest:

# import pandas as pd
import ray.dataframe as pd

#use pd as usual
Więcej szczegółów można przeczytać tutaj:

Https://rise.cs.berkeley.edu/blog/pandas-on-ray/

 21
Author: lev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-18 09:30:39

Jeszcze jedna odmiana

Wiele operacji wykonywanych w Pandzie może być również wykonanych jako zapytanie db (sql, mongo)

Dzięki temu, że dane są przechowywane w pamięci podręcznej, mogą być przechowywane w pamięci podręcznej i mogą być przechowywane w pamięci podręcznej.]}

Później możesz wykonać post processing używając pand.

Zaletą tej metody jest to, że uzyskujesz optymalizacje DB do pracy z dużymi danymi, jednocześnie definiując logikę w składnia deklaratywna na wysokim poziomie - bez konieczności zajmowania się szczegółami decydowania, co robić w pamięci, a co robić poza rdzeniem.

I chociaż język zapytań i pandy są różne, zwykle nie jest skomplikowane tłumaczenie części logiki z jednego na drugi.

 20
Author: Ophir Yoktan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-28 05:22:21

Rozważ Ruffus jeśli wybierzesz prostą ścieżkę tworzenia potoku danych, który jest podzielony na wiele mniejszych plików.

 13
Author: Golf Monkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-09 19:07:16

Chciałbym zwrócić uwagę na pakiet Vaex.

Vaex jest biblioteką Pythona dla leniwych ramek danych (podobnych do pand), do wizualizacji i eksploracji dużych zbiorów danych tabelarycznych. Może obliczać statystyki, takie jak średnia, suma, liczba, odchylenie standardowe itp., na siatce n-wymiarowej do miliarda (109) obiektów / wierszy na sekundę. Wizualizacja odbywa się za pomocą histogramów, Wykresów gęstości i renderowania objętości 3d, umożliwiając interaktywną eksplorację dużych danych. Vaex wykorzystuje pamięć mapowanie, polityka zerowej kopii pamięci i leniwe obliczenia dla najlepszej wydajności (brak marnowania pamięci).

Zajrzyj do dokumentacji: https://vaex.readthedocs.io/en/latest / API jest bardzo zbliżone do API pand.

 11
Author: Rob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-03 09:40:50

Ostatnio natknąłem się na podobny problem. Znalazłem po prostu czytanie danych w kawałkach i dołączanie ich, gdy piszę je w kawałkach do tego samego pliku csv działa dobrze. Moim problemem było dodanie kolumny daty na podstawie informacji w innej tabeli, używając wartości niektórych kolumn w następujący sposób. Może to pomóc tym, którzy są zdezorientowani przez dask i hdf5, ale bardziej zaznajomieni z pandami takimi jak ja.

def addDateColumn():
"""Adds time to the daily rainfall data. Reads the csv as chunks of 100k 
   rows at a time and outputs them, appending as needed, to a single csv. 
   Uses the column of the raster names to get the date.
"""
    df = pd.read_csv(pathlist[1]+"CHIRPS_tanz.csv", iterator=True, 
                     chunksize=100000) #read csv file as 100k chunks

    '''Do some stuff'''

    count = 1 #for indexing item in time list 
    for chunk in df: #for each 100k rows
        newtime = [] #empty list to append repeating times for different rows
        toiterate = chunk[chunk.columns[2]] #ID of raster nums to base time
        while count <= toiterate.max():
            for i in toiterate: 
                if i ==count:
                    newtime.append(newyears[count])
            count+=1
        print "Finished", str(chunknum), "chunks"
        chunk["time"] = newtime #create new column in dataframe based on time
        outname = "CHIRPS_tanz_time2.csv"
        #append each output to same csv, using no header
        chunk.to_csv(pathlist[2]+outname, mode='a', header=None, index=None)
 10
Author: timpjohns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-04 15:32:56

W tej chwili pracuję " jak " ty, tylko na mniejszą skalę, dlatego nie mam PoC dla mojej sugestii.

Wydaje mi się jednak, że odnajduję sukces w użyciu pickle ' a jako systemu buforowania i outsourcingu wykonywania różnych funkcji do plików-wykonywanie tych plików z mojego commando / main file; na przykład używam prepare_use.py aby przekonwertować typy obiektów, podziel zestaw danych na zestaw danych testowych, walidacyjnych i predykcyjnych.

Jak działa buforowanie z pickle? Używam sznurków w celu uzyskania dostępu do pickle-plików, które są dynamicznie tworzone, w zależności od tego, jakie parametry i zbiory danych zostały przekazane (z tym staram się przechwycić i określić, czy program był już uruchomiony, za pomocą .shape dla zestawu danych, dict dla przekazywanych parametrów). Szanując te środki, dostaję ciąg, aby spróbować znaleźć i przeczytać .pickle-plik i może, jeśli zostanie znaleziony, pominąć czas przetwarzania, aby przejść do wykonania, nad którym obecnie pracuję.

Korzystając z baz danych napotkałem podobne problemy, czyli dlaczego jednak cieszy mnie korzystanie z tego rozwiązania - na pewno jest wiele ograniczeń - na przykład przechowywanie ogromnych zestawów ogórków ze względu na redundancję. Aktualizacja tabeli z przed do po transformacji może być wykonywana z odpowiednim indeksowaniem - Walidacja informacji otwiera całą inną książkę (próbowałem skonsolidować dane indeksowane i przestałem korzystać z bazy danych po 2 godzinach zasadniczo - jak chciałbym skakać z powrotem po każdym procesie transformacji)

Mam nadzieję, że moje 2 grosze pomogą Ci w jakimś sposób.

Pozdrawiam.

 -1
Author: TiRoX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-08 14:05:14

Dlaczego Pandy ? Czy próbowałeś standardowego Pythona?

Użycie biblioteki standardowej Pythona. Pandas jest przedmiotem częstych aktualizacji, nawet w ostatnim wydaniu stabilnej wersji.

Używając standardowej biblioteki Pythona Twój kod będzie zawsze uruchamiany.

Jednym ze sposobów na zrobienie tego jest wyobrażenie sobie, w jaki sposób chcesz, aby Twoje dane były przechowywane i jakie pytania chcesz rozwiązać dotyczące danych. Następnie narysuj schemat organizowania danych (tabel myślowych), które pomoże Ci wyszukać dane, niekoniecznie normalizację.

Możesz dobrze wykorzystać:

    Lista słowników do przechowywania danych w pamięci (Think Amazon EC2) lub na dysku, jeden dict to jeden wiersz,
  • generatory do przetwarzania danych wiersz po wierszu, aby nie przepełniać pamięci RAM,
  • zrozumienie listy do zapytania danych,
  • użyj Counter, DefaultDict, ...
  • przechowuj dane na dysku twardym, używając dowolnego wybranego rozwiązania do przechowywania, json może być jednym z nich.

Ram i HDD stają się z czasem coraz tańsze, a standardowy python 3 jest powszechnie dostępny i stabilny.

Fondamental pytanie, które próbujesz rozwiązać, to " jak odpytywać duże zbiory danych ?". Architektura hdfs jest mniej więcej tym, co tutaj opisuję (modelowanie danych z danymi zapisywanymi na dysku).

Załóżmy, że masz 1000 petabajtów danych, nie ma mowy, że będziesz mógł je przechowywać w Dasku lub pandach, twoje największe szanse oto, aby przechowywać go na dysku i przetwarzać go za pomocą generatorów.

 -10
Author: Pelican,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-23 11:48:03