Привет! В настоящее время я делаю следующее, чтобы найти все уникальные предметы в нескольких сериях панд:
In [44]: data = [Series([1,2,7,4]), Series([2,5,3,1]), Series([3, 2, 4])]
In [45]: counts = Counter(chain.from_iterable(data))
In [46]: unique_occurrences = [item for item, count in counts.items() if count == 1]
In [47]: unique_occurrences
Out[47]: [7, 5]
Есть ли способ ускорить это, поскольку реальные данные велики.
Спасибо.
Отзывы об ответах
Код:
def uniq_0(data): # Original
counts = Counter(chain.from_iterable(data))
return [item for item, count in counts.items() if count == 1]
def uniq_1(data): # Divakar #1
a = np.concatenate(data)
unq,c = np.unique(a, return_counts=1)
return unq[c==1]
def uniq_2(data): # Divakar #2
a = np.concatenate(data)
return np.flatnonzero(np.bincount(a)==1)
def uniq_3(data): # Divakar #3
counts = Counter(chain.from_iterable(data))
k = np.array(list(counts.keys()))
v = np.array(list(counts.values()))
return k[v==1]
def uniq_4(data): # Divakar #4
L = max([i.max() for i in data])+1
return np.flatnonzero(np.sum([np.bincount(i,minlength=L)
for i in data],axis=0)==1)
def uniq_5(data): # Divakar #5
L = max([i.max() for i in data])+1
sums = np.zeros(L,dtype=int)
for i in data:
sums += np.bincount(i,minlength=L)
return np.flatnonzero(sums==1)
def uniq_6(data): # Erfan
v = pd.concat(data).value_counts()
return v.index[v == 1]
if __name__ == '__main__':
data = [Series([1,2,7,4]), Series([2,5,3,1]), Series([3, 2, 4])]
funcs = [uniq_0, uniq_1, uniq_2, uniq_3, uniq_4, uniq_5, uniq_6]
answers = [f(data) for f in funcs]
golden = set(answers[0])
check = [set(a) == golden for a in answers]
for n, a in enumerate(answers):
if set(a) != golden:
print(f' Error with uniq_{n}(data)')
else:
print(f' Confirmed uniq_{n}(data) == golden')
Сессия Spyder:
Confirmed uniq_0(data) == golden
Confirmed uniq_1(data) == golden
Confirmed uniq_2(data) == golden
Confirmed uniq_3(data) == golden
Confirmed uniq_4(data) == golden
Confirmed uniq_5(data) == golden
Confirmed uniq_6(data) == golden
In [73]: # 1000 Series. Averaging 10000.0 ints/Series. 405 ints unique.
In [74]: for f in funcs:
...: print(f.__name__, end=': ')
...: %timeit -r 3 f(data2)
uniq_0: 2.21 s ± 18.5 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
uniq_1: 465 ms ± 2.5 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
uniq_2: 126 ms ± 215 µs per loop (mean ± std. dev. of 3 runs, 10 loops each)
uniq_3: 2.22 s ± 48.6 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
uniq_4: 1.12 s ± 10.8 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
uniq_5: 374 ms ± 1.28 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
uniq_6: 831 ms ± 20.6 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)
In [75]:
Комментарий
Большое спасибо тебе.Мои фактические данные больше, но они не помещаются на этом ноутбуке, но я чувствую, что теперь у меня есть достаточно вариантов, чтобы по-настоящему это зафиксировать. Еще раз спасибо !