Zaczynam od dokumentów DataFrame pand tutaj: http://pandas.pydata.org/pandas-docs/stable/dsintro.html
Chciałbym iteracyjnie wypełnić DataFrame wartościami w rodzaju obliczeń szeregów czasowych. Zasadniczo chciałbym zainicjować ramkę danych z kolumnami A, B i wierszami znaczników czasu, wszystkie 0 lub wszystkie NaN.
Następnie dodałbym wartości początkowe i przejrzałem te dane, obliczając nowy wiersz z rzędu przed, powiedzmy row[A][t] = row[A][t-1]+1
lub tak.
Obecnie używam kodu jak poniżej, ale czuję, że jest to trochę brzydkie i musi istnieć sposób, aby to zrobić bezpośrednio z DataFrame, lub po prostu lepszy sposób w ogóle. Uwaga: używam Python 2.7.
import datetime as dt
import pandas as pd
import scipy as s
if __name__ == '__main__':
base = dt.datetime.today().date()
dates = [ base - dt.timedelta(days=x) for x in range(0,10) ]
dates.sort()
valdict = {}
symbols = ['A','B', 'C']
for symb in symbols:
valdict[symb] = pd.Series( s.zeros( len(dates)), dates )
for thedate in dates:
if thedate > dates[0]:
for symb in valdict:
valdict[symb][thedate] = 1+valdict[symb][thedate - dt.timedelta(days=1)]
print valdict
.append
w pd od dołączania listy? Wiem, że.append
w pandach kopiuje cały zestaw danych do nowego obiektu ´, czy dołączane pytony działają inaczej?Odpowiedzi:
Oto kilka sugestii:
Użyj
date_range
dla indeksu:Uwaga: możemy utworzyć pustą ramkę danych (z
NaN
s), pisząc:Aby wykonać tego typu obliczenia dla danych, użyj tablicy numpy:
Dlatego możemy stworzyć DataFrame:
źródło
index
x0
(columns = []
) i dołączanie jednej kolumny w każdym zwoju pętli. Mam na myślidf[col_name] = pandas.Series([...])
w pętli iterującej nazwy kolumn. W pierwszym przypadku nie tylko przydział pamięci zajmuje dużo czasu, ale zastępowanie NaN nowymi wartościami wydaje się niezwykle powolne.Jeśli chcesz po prostu utworzyć pustą ramkę danych i wypełnić ją później niektórymi ramkami danych przychodzących, spróbuj tego:
W tym przykładzie używam tego dokumentu pandy do utworzenia nowej ramki danych, a następnie używam append do zapisu do newDF z danymi ze staregoDF.
Jeśli muszę dodawać nowe dane do tego nowego pliku z więcej niż jednego starego pliku, po prostu używam pętli for, aby iterować po pandas.DataFrame.append ()
źródło
append
(i podobnieconcat
) za każdym razem kopiuje pełny zestaw danych do nowego obiektu, dlatego iteracja i dołączanie może i spowoduje znaczny spadek wydajności. Aby uzyskać więcej informacji, patrz: pandas.pydata.org/pandas-docs/stable/merging.htmlWłaściwy sposób ™ do utworzenia DataFrame
Większość odpowiedzi tutaj powie ci, jak utworzyć pustą ramkę danych i wypełnić ją, ale nikt nie powie ci, że to źle.
Oto moja rada: poczekaj, aż będziesz mieć pewność, że masz wszystkie dane, z którymi musisz pracować. Użyj listy, aby zebrać swoje dane, a następnie zainicjuj ramkę DataFrame, gdy będziesz gotowy.
To jest zawsze tańsze, aby dołączyć do listy i utworzyć DataFrame za jednym razem , niż jest, aby utworzyć pusty DataFrame (lub jedną z Nans) i dołączyć do niej w kółko. Listy zajmują również mniej pamięci i są znacznie lżejszą strukturą danych do pracy , dołączania i usuwania (w razie potrzeby).
Inną zaletą tej metody jest
dtypes
automatyczne wnioskowanie (zamiast przypisywaniaobject
ich wszystkim).Ostatnią zaletą jest to, że jest tworzony automatycznie dla swoich danych , więc jest to jeden mniej rzeczy się martwić (spójrz na biednych i metodach poniżej, widać zarówno elementy, które wymagają obsługi indeksu odpowiednio).
RangeIndex
append
loc
Rzeczy, których NIE powinieneś robić
append
lubconcat
wewnątrz pętliOto największy błąd, jaki widziałem od początkujących:
Pamięć jest przydzielana ponownie dla każdej operacji
append
lubconcat
operacji. Połącz to z pętlą, a otrzymasz kwadratową operację złożoności . Ze stronydf.append
dokumentu :Innym błędem związanym z
df.append
tym jest to, że użytkownicy często zapominają, że append nie jest funkcją lokalną , więc wynik należy przypisać z powrotem. Musisz także martwić się o typy:Radzenie sobie z kolumnami obiektów nigdy nie jest dobrą rzeczą, ponieważ pandy nie mogą wektoryzować operacji na tych kolumnach. Musisz to zrobić, aby to naprawić:
loc
wewnątrz pętliWidziałem również
loc
używane do dołączania do DataFrame, który został utworzony pusty:Tak jak poprzednio, nie przydzielono wstępnie wymaganej ilości pamięci za każdym razem, więc pamięć jest odnawiana za każdym razem, gdy tworzysz nowy wiersz . Jest tak samo zły, jak
append
i jeszcze bardziej brzydki.Pusta ramka danych dla NaNs
Następnie powstaje ramka danych NaNs i wszystkie związane z tym zastrzeżenia.
Tworzy ramkę danych kolumn obiektowych, podobnie jak inne.
Dołączanie nadal ma wszystkie problemy, jak powyższe metody.
Dowód jest w budyniu
Pomiar tych metod jest najszybszym sposobem, aby zobaczyć, jak bardzo różnią się one pod względem pamięci i użyteczności.
Kod porównawczy w celach informacyjnych.
źródło
Zainicjuj pustą ramkę za pomocą nazw kolumn
Dodaj nowy rekord do ramki
Możesz także przekazać słownik:
Dołącz kolejną ramkę do istniejącej ramki
Uwagi dotyczące wydajności
Jeśli dodajesz wiersze wewnątrz pętli, rozważ problemy z wydajnością. W przypadku około 1000 pierwszych rekordów wydajność „my_df.loc” jest lepsza, ale stopniowo staje się wolniejsza przez zwiększenie liczby rekordów w pętli.
Jeśli planujesz robić cienkie elementy w dużej pętli (powiedzmy, że około 10M rekordów), lepiej jest użyć kombinacji tych dwóch; wypełnij ramkę danych iloc, aż rozmiar osiągnie około 1000, następnie dołącz ją do oryginalnej ramki danych i opróżnij tymczasową ramkę danych. Zwiększy to twoją wydajność około 10 razy.
źródło
my_df = my_df.append(my_df2)
nie działa dla mnie, chyba że podamignore_index=True
.Załóżmy ramkę danych z 19 wierszami
Utrzymywanie kolumny A jako stałej
Zachowanie kolumny b jako zmiennej podanej przez pętlę
Możesz zamienić pierwsze x na
pd.Series([x], index = [x])
dowolną wartośćźródło