Mam ten wyjątkowy wymóg, który można wyjaśnić za pomocą tego kodu. To działa kod, ale nie jest wydajne pod względem pamięci.
data = [[
"A 5408599",
"B 8126880",
"A 2003529",
],
[
"C 9925336",
"C 3705674",
"A 823678571",
"C 3205170186",
],
[
"C 9772980",
"B 8960327",
"C 4185139021",
"D 1226285245",
"C 2523866271",
"D 2940954504",
"D 5083193",
]]
temp_dict = {
item: index for index, sublist in enumerate(data)
for item in sublist
}
print(data[temp_dict["A 2003529"]])
out: ['A 5408599', 'B 8126880', 'A 2003529']
Krótko mówiąc, chcę, aby każdy element listy podrzędnej był indeksowalny i powinien zwrócić podlistę.
Powyższa metoda działa, ale zajmuje dużo pamięci, gdy dane są duże. Czy jest jakiś lepszy sposób, przyjazny dla pamięci i procesora? Dane są przechowywane jako plik JSON.
Edytuj Próbowałem odpowiedzi dla największego możliwego scenariusza przypadku użycia (1000 list podrzędnych, 100 pozycji w każdej liście podrzędnej, 1 milion zapytań) i oto wyniki (średnio 10 przebiegów):
Method, Time (seconds), Extra Memory used
my, 0.637 40 Mb
deceze, 0.63 40 Mb
James, 0.78 200 kb
Pant, > 300 0 kb
mcsoini, forever 0 kb
{item: sublist for sublist in data for item in sublist}
może być nieco bardziej wydajny i bezpośredni… ?!Odpowiedzi:
Naprawdę jesteś w miejscu na kompromis między czasem / pamięcią potrzebną do wygenerowania słownika a czasem potrzebnym do przeskanowania wszystkich danych w celu znalezienia metody „w locie”.
Jeśli chcesz zastosować metodę niskiej pamięci, możesz użyć funkcji, która przeszukuje każdą podlistę pod kątem wartości. Użycie generatora przyspieszy początkowe wyniki dla użytkownika, ale w przypadku dużych zestawów danych będzie to powolne między zwrotami.
Jak wspomniano w komentarzach, dobrym pomysłem może być zbudowanie tabeli skrótów opartej tylko na pierwszej literze lub pierwszych 2 lub 3 znakach. Umożliwi to zbudowanie listy kandydackiej list podrzędnych, a następnie skanowanie ich w celu sprawdzenia, czy wartość znajduje się na liście podrzędnej.
quick_hash
Budowa tego kodu zajmie trochę czasu, ponieważ skanujesz całą strukturę danych. Jednak ślad stopy pamięci będzie znacznie mniejszy. Głównym parametrem dostrajania wydajności jestsize
. Mniejszy rozmiar będzie miał mniejszą pamięć, ale będzie działał dłużej,find_list_by_hash
ponieważ twoja pula kandydatów będzie większa. Możesz przeprowadzić testy, aby sprawdzić, jakie prawosize
powinno przysługiwać Twoim danym. Pamiętaj tylko, że wszystkie twoje wartości są przynajmniej tak długiesize
.źródło
Możesz spróbować czegoś takiego:
Nie trzeba tworzyć struktury mapowania.
źródło
spróbuj tego, używając pand
wygląda to na proste rozwiązanie, nawet jeśli Twoje dane rosną, poradzi sobie z tym skutecznie
źródło
df
: jest znacznie większy niż listadata
(> x12) i słowniktemp_dict
(~ x2) dla podanych danych przykładowych - powiedziałbym, że nie do końca wydajna pod względem pamięcipandas
poradzi sobie z tym problemem bardziej wydajnie niż wbudowana funkcjonalność Pythona.pandas
jeśli można to zrobić za pomocąstdlib
. Tylko dlatego, że wygląda fantazyjnie?Nie jestem do końca pewien, jak to by się zachowało w przypadku większych ilości danych, ale możesz spróbować czegoś w stylu:
Edycja: Wydaje się nie być korzystna pod względem czasu, na podstawie szybkiego testu z fałszywymi danymi na większą skalę.
źródło