Muszę dopasować dwie bardzo duże tablice Numpy (jedna to 20000 wierszy, a kolejne około 100000 wierszy) i próbuję zbudować skrypt, aby to zrobić wydajnie. Prosta pętla nad tablicami jest niesamowicie powolna, czy ktoś może zaproponować lepszy sposób? Oto, co próbuję zrobić: tablica datesSecondDict
i tablica pwfs2Dates
zawierają wartości datetime, muszę wziąć każdą wartość datetime z tablicy pwfs2Dates
(mniejsza tablica) i sprawdzić, czy istnieje wartość datetime (plus minus 5 minut) w tablicy datesSecondDict
(może być ich więcej niż 1). Jeśli istnieje jeden (lub więcej), zapełniam nową tablicę (o tym samym rozmiarze co tablica pwfs2Dates
) z wartością (jedną z wartości) z tablicy valsSecondDict
(która jest po prostu tablicą z odpowiednimi wartościami liczbowymi do datesSecondDict
). Oto rozwiązanie przez @unutbu i @joaquin że pracował dla mnie (dzięki chłopaki!):Dopasowanie warunkowe tablicy Numpy
import time
import datetime as dt
import numpy as np
def combineArs(dict1, dict2):
"""Combine data from 2 dictionaries into a list.
dict1 contains primary data (e.g. seeing parameter).
The function compares each timestamp in dict1 to dict2
to see if there is a matching timestamp record(s)
in dict2 (plus/minus 5 minutes).
==If yes: a list called data gets appended with the
corresponding parameter value from dict2.
(Note that if there are more than 1 record matching,
the first occuring value gets appended to the list).
==If no: a list called data gets appended with 0."""
# Specify the keys to use
pwfs2Key = 'pwfs2:dc:seeing'
dimmKey = 'ws:seeFwhm'
# Create an iterator for primary dict
datesPrimDictIter = iter(dict1[pwfs2Key]['datetimes'])
# Take the first timestamp value in primary dict
nextDatePrimDict = next(datesPrimDictIter)
# Split the second dictionary into lists
datesSecondDict = dict2[dimmKey]['datetime']
valsSecondDict = dict2[dimmKey]['values']
# Define time window
fiveMins = dt.timedelta(minutes = 5)
data = []
#st = time.time()
for i, nextDateSecondDict in enumerate(datesSecondDict):
try:
while nextDatePrimDict < nextDateSecondDict - fiveMins:
# If there is no match: append zero and move on
data.append(0)
nextDatePrimDict = next(datesPrimDictIter)
while nextDatePrimDict < nextDateSecondDict + fiveMins:
# If there is a match: append the value of second dict
data.append(valsSecondDict[i])
nextDatePrimDict = next(datesPrimDictIter)
except StopIteration:
break
data = np.array(data)
#st = time.time() - st
return data
Dzięki Aina.
dzięki tak dużo, że całkowicie udało się! – Aina