Более быстрые коллекции. Работа в стиле «как у панд»

1

Привет! В настоящее время я делаю следующее, чтобы найти все уникальные предметы в нескольких сериях панд:

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]

Есть ли способ ускорить это, поскольку реальные данные велики.

Благодарю.

  • 0
    Всегда ли в серии будут положительные целые числа?
  • 1
    Это всегда было бы + ve Ints. Я приму время некоторые из этих ответов ниже и дам обратную связь.
Теги:
pandas
numpy

2 ответа

2

Подход № 1

Здесь один массив на основе NumPy -

a = np.concatenate(data)
unq,c = np.unique(a, return_counts=1)
out = unq[c==1]

Подход № 2 (для положительных целых данных)

Для положительных данных целых чисел, мы можем использовать np.bincount, чтобы получить out непосредственно из - a

out = np.flatnonzero(np.bincount(a)==1) # a from app#1

Подход № 3

Если мы хотим использовать counts, которые мы могли бы предпочесть при работе с очень большим числом рядов, конкатенация могла бы быть медленнее в этом сценарии -

k = np.array(list(counts.keys()))
v = np.array(list(counts.values()))
out = k[v==1]

Подход № 4 (для положительных целых данных)

С большим количеством рядов, содержащих положительные целые числа, мы можем использовать bincount для каждого и, таким образом, избежать конкатенации -

L = max([i.max() for i in data])+1
out = np.flatnonzero(np.sum([np.bincount(i,minlength=L) for i in data],axis=0)==1)

Подход № 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)
out = np.flatnonzero(sums==1)
1

Мы можем использовать pd.concat в сочетании с value_counts и применять логическое индексирование:

v = pd.concat(data).value_counts()
v.index[v == 1].to_numpy()

Который дает

array([7, 5], dtype=int64)

Заметка
Если ваша версия для панд <0.24.0, используйте вместо:

v.index[v == 1].values

Узнайте больше здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню