У меня проблема с фильтрацией фрейма данных pandas.
city
NYC
NYC
NYC
NYC
SYD
SYD
SEL
SEL
...
df.city.value_counts()
Я хотел бы удалить ряды городов, у которых частота подсчета меньше 4, например, SYD и SEL.
Как можно было бы сделать это, не отбрасывая их вручную город за городом?
Я думал, что это можно сделать, используя, например, df.drop (['SYD']), но не работал.






Это один из способов использования pd.Series.value_counts.
counts = df['city'].value_counts()
res = df[~df['city'].isin(counts[counts < 5].index)]
counts - это объект pd.Series. counts < 5 возвращает логический ряд. Мы фильтруем ряды счетчиков по логическому ряду counts < 5 (это то, чего достигают квадратные скобки). Затем мы берем индекс результирующего ряда, чтобы найти города с <5 подсчетами. ~ - оператор отрицания.
Помните, что серия - это отображение между индексом и значением. Индекс серии не обязательно содержит уникальные значения, но это гарантировано выводом value_counts.
Большое спасибо! теперь мне нужно разобраться в значении "~"
@DevinLee, это просто означает поэлементное «отрицание» / «отрицание» в векторизованных функциях.
Я не понимаю эту часть counts[counts < 5].index. Вы можете уточнить?
@Snow, counts - это объект pd.Series. counts < 5 возвращает логический ряд. Мы фильтруем серию counts по логической серии counts < 5 (этого и достигают квадратные скобки). Затем мы берем индекс результирующего ряда, чтобы найти города с <5 подсчетами. Помните, что серия - это отображение между индексом и значением. Индекс не обязательно содержит уникальные значения, но с value_counts это гарантировано.
Я думаю ты ищешь value_counts()
# Import the great and powerful pandas
import pandas as pd
# Create some example data
df = pd.DataFrame({
'city': ['NYC', 'NYC', 'SYD', 'NYC', 'SEL', 'NYC', 'NYC']
})
# Get the count of each value
value_counts = df['city'].value_counts()
# Select the values where the count is less than 3 (or 5 if you like)
to_remove = value_counts[value_counts <= 3].index
# Keep rows where the city column is not in to_remove
df = df[~df.city.isin(to_remove)]
А вот и фильтр
df.groupby('city').filter(lambda x : len(x)>3)
Out[1743]:
city
0 NYC
1 NYC
2 NYC
3 NYC
Решение второе transform
sub_df = df[df.groupby('city').city.transform('count')>3].copy()
# add copy for future warning when you need to modify the sub df
Это фантастический лайнер! Мне действительно нужно больше использовать groupby, на данный момент для меня это все еще разновидность черной магии.
Хороший. К сожалению, от lambda меня тошнит :(. Только в малых дозах!
@jpp да, для небольшого размера выборки, я думаю, фильтр более понятен, но только для небольшого размера выборки
Протестированное на фрейме данных с 1 миллионом строк, решение jpp value_counts немного быстрее, чем решение filter, но решение transform намного быстрее, чем оба решения (последнее заняло менее 1 с в моем наборе данных, тогда как другие заняли 5,7 и 8,3 с соответственно. ).
Другое решение:
threshold=3
df['Count'] = df.groupby('City')['City'].transform(pd.Series.value_counts)
df=df[df['Count']>=threshold]
df.drop(['Count'], axis = 1, inplace = True)
print(df)
City
0 NYC
1 NYC
2 NYC
3 NYC
К сожалению, это решение намного медленнее, чем другие.
что такое
dropping them city by city? возможно, вам стоит предоставить свой рабочий код. и что ты хочешь.