#python #python-3.x #regex #pandas
#python #python-3.x #регулярное выражение #pandas
Вопрос:
import pandas as pd
list = ['apple','banana','cherries','dragonfruit','elderberry']
data = {'name': ['Alpha', 'Bravo','Charlie','Delta','Echo'],
'favorite_fruit': ['apple banana cherries', 'banana cherries dragonfruit',
'cherries dragonfruit','dragonfruit','apple elderberry']}
df = pd.DataFrame (data, columns = ['name','favorite_fruit'])
Я хочу подсчитать частоту каждого фрукта в list
в df.
Ожидаемый результат:
df2
Fruit | Frequency
Apple | 2
Banana | 2
Cherries | 3
Dragonfruit | 3
Elderberry | 1
Код df.favorite_fruit.str.split(expand=True).stack().value_counts()
работает для небольшого фрейма данных.
Если df.favorite_fruit
содержит тысячи строк с различными комбинациями фруктов,
как мне найти только частоту слов в list
?
Ответ №1:
Возможно, это ответ с петлей, но вы можете просто отфильтровать значения из ответа, который вы уже описали. Итак, если вы начнете с этого:
>>> df2 = df.favorite_fruit.str.split(expand=True).stack()
>>> df2
0 0 apple
1 banana
2 cherries
1 0 banana
1 cherries
2 dragonfruit
2 0 cherries
1 dragonfruit
3 0 dragonfruit
4 0 apple
1 elderberry
dtype: object
Вы могли бы использовать isin
, чтобы ограничить данные теми, которые находятся в целевом списке:
>>> target = ['apple', 'banana']
>>> df2[df2.isin(target)].value_counts()
banana 2
apple 2
dtype: int64
Или даже после вашего первоначального ответа:
>>> df.favorite_fruit.str.split(expand=True).stack().value_counts().loc[target]
apple 2
banana 2
dtype: int64
Если проблема в том, что операции expand
и stack
являются дорогостоящими с таким количеством данных, то, возможно, это не будет удовлетворительным. Но я думаю, возможно, это может быть лучше, чем ответы на основе цикла?
Комментарии:
1. Использование первой части ответа-лазейки работает, но вторая часть кода
df.favorite_fruit.str.split(expand=True).stack().value_counts().loc[target]
возвращает ошибку ключа: «Передача списка-нравится » . loc или [] с отсутствующими метками больше не поддерживаются, ,см. pandas.pydata.org/pandas-docs/stable/user_guide /… ‘. Я изменил . loc в .reindex но это не работает. Вторая часть кода, если она работает, будет лучше, поскольку она не добавляет больше переменных..2. @Luc хммм, у меня это работает — я копирую / вставляю эту строку сразу после вашей
df = pd.DataFrame....
строки из вашего примера и не получаю ошибок (также сtarget = ['apple', 'banana']
определенным). Серия, возвращаемаяvalue_counts()
, должна иметь значения фруктов в качестве индекса, поэтому вы должны иметь возможность использоватьloc
с вашими названиями фруктов для индексации3. возможно, это потому, что у меня отсутствуют метки в моих реальных данных. Тем не менее, если второе решение не работает. Подойдет первый, хотя тогда я создам много переменных. Спасибо!
4. pandas.pydata.org/pandas-docs/stable/user_guide/…
5. @Luc ahhh это в ваших реальных данных — эта ошибка должна означать, что одного из ваших целевых слов нет в фрейме данных / значение имеет значение — возможно ли это? Но в этом случае
df.favorite_fruit.str.split(expand=True).stack().value_counts().reindex(target)
работает и для меня.
Ответ №2:
Возможно, это немного окольный способ сделать это, но если ваш favorite_fruit
столбец всегда разделен пробелом, что-то вроде этого должно сработать:
import pandas as pd
list = ['apple','banana','cherries','dragonfruit','elderberry']
data = {'name': ['Alpha', 'Bravo','Charlie','Delta','Echo'],
'favorite_fruit': ['apple banana cherries', 'banana cherries dragonfruit',
'cherries dragonfruit','dragonfruit','apple elderberry']}
df = pd.DataFrame (data, columns = ['name','favorite_fruit'])
new_df = pd.DataFrame()
data = {}
for i, row in df.iterrows():
s = row['favorite_fruit']
items = s.split(' ')
for item in items:
if item in data.keys():
data[item].append(1)
else:
data[item] = [1]
for key, value in data.items():
data[key] = sum(value)
fruit = []
frequency = []
for key, value in data.items():
fruit.append(key)
frequency.append(value)
new_df = pd.DataFrame({'fruit': fruit, 'frequency':frequency})
print(new_df)
При этом выводится следующее:
fruit frequency
0 apple 2
1 banana 2
2 cherries 3
3 dragonfruit 3
4 elderberry 1
Комментарии:
1. извините, это близко, но не совсем подходит для моей «реальной» проблемы.
favorite_fruit
— это строка, содержащая предложение, которое иногда содержит запятую и смайлики. Приведенный выше код дает мне частоту всех слов вfavorite_fruit
столбце, а не только частоту слов вlist
.2. Что ж, тогда вам нужно обновить и отредактировать свой минимальный рабочий пример, чтобы отразить это … иначе мы не сможем вам помочь…
Ответ №3:
Попробуйте использовать функцию разнесения после разделения.
df.favorite_fruit.str.split().explode().value_counts()
cherries 3
dragonfruit 3
banana 2
apple 2
elderberry 1
Name: favorite_fruit, dtype: int64