#python #pandas #dataframe #unique-values
Вопрос:
У меня есть фрейм данных Pandas с данными Facebook, собранными с помощью Crowdtangle, где я хотел бы получить уникальные значения некоторых столбцов.
Для большинства столбцов такое выражение отлично работает: df.column_name.unique(). Пример:
In: df.account_name.unique()
Out: array(['YO TE BANCO VICTOR HUGO MORALES!!!',
'Lula de novo, com a força do povo',
'SOCIEDADE CIVIL, LEVANTA E RESISTE !', ..., 'Steemit',
'BOLSONARO REELEITO EM 2022',
'WE SUPPORT HUMAN RIGHTS OF SHIAS WORLDWIDE!'], dtype=object)
Однако для некоторых столбцов такая команда не работает. Вместо этого я получаю ошибку типа: недоступный тип: «список». Например, когда я набираю этот код: df.country_mentions_domestic.unique().
Я попытался посмотреть другие примеры этого сообщения об ошибке, но безуспешно. Может кто-нибудь понять, в чем может быть проблема?
Пример полного сообщения об ошибке:
In: df.country_mentions_domestic.unique()
Out: TypeError Traceback (most recent call last)
/var/folders/8k/lzt5y36n293d8wkk3svczgnr0000gn/T/ipykernel_2389/3653985748.py in <module>
----> 1 df_fb.country_mentions_domestic.unique()
2 # print()
3 # print(df_country_mentions_en.unique())
4 # print()
5 # print(df_country_mentions_ru_text.unique())
/usr/local/Cellar/jupyterlab/3.1.10/libexec/lib/python3.9/site-packages/pandas/core/series.py in unique(self)
2037 Categories (3, object): ['a' < 'b' < 'c']
2038 """
-> 2039 return super().unique()
2040
2041 @overload
/usr/local/Cellar/jupyterlab/3.1.10/libexec/lib/python3.9/site-packages/pandas/core/base.py in unique(self)
977 result = np.asarray(result)
978 else:
--> 979 result = unique1d(values)
980
981 return result
/usr/local/Cellar/jupyterlab/3.1.10/libexec/lib/python3.9/site-packages/pandas/core/algorithms.py in unique(values)
429
430 table = htable(len(values))
--> 431 uniques = table.unique(values)
432 uniques = _reconstruct_data(uniques, original.dtype, original)
433 return uniques
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.unique()
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable._unique()
TypeError: unhashable type: 'list'
Ответ №1:
Это означает, что по крайней мере одно (если не больше) из значений в этом столбце list
не является строкой.
.unique()
Функция сравнивает значения в столбце друг с другом, используя их хэш-значения. Поскольку списки python изменчивы (т. Е. Они могут изменять содержимое), с ними не может быть связано фиксированное хэш-значение.
Вы можете выяснить, какие из них с чем-то подобным:
df[[isinstance(val, list) for val in df.country_mentions_domestic.values]]
Если вам действительно нужно, чтобы у некоторых из них были коллекции значений, вы можете преобразовать свои списки в кортежи (или в строки, разделенные чем-то вроде точки с запятой). Кортежи не изменяются, поэтому их можно хэшировать.
Комментарии:
1. Большое спасибо за ваш ответ! Я попробовал команду «df[[isinstance…», и результатом является длина всего кадра данных (поэтому все значения кажутся «списком»). Поэтому я попытался превратить весь столбец в кортеж. Но следующий код выдает ту же ошибку типа, что и выше (тип без хэша: «список»): «ПЕРВАЯ СТРОКА: df.country_mentions_en = кортеж(df.country_mentions_en), ВТОРАЯ СТРОКА: df.country_mentions_en.уникальный()». У вас есть идея, как поступить вместо этого?
2. Каждый элемент в столбце выглядит как список, поэтому вам нужно изменить их на кортежи по одному за раз. Измените первую строку на:
df.country_mentions_en = [tuple(l) for l in df.country_mentions_en.values]
3. Кроме того, если вам нужны уникальные элементы списка в списках, вам необходимо их распаковать. НАПРИМЕР, если в вашем столбце два кортежа:
('A', 'B')
и('B', 'C')
, то вывод.unique()
будет('A', 'B'), ('B', 'C')
. Но если вы хотите'A', 'B', 'C'
получить выходные данные, один из подходов состоит в том, чтобы использоватьchain
функцию fromitertools
для их распаковки и структуруset
данных для получения уникальных значений:set(chain(*df.column_name))