Задача по Pandas. Сложная фильтрация
Подскажите, прохожу обучение, не могу перешагнуть задание.
Отфильтруйте строки таким образом, чтобы оставить только те транзакции, у которых в соответствующий относительный день tr_day количество уникальных MCC кодов при транзакциях было больше 75. Пробовал играться с группировками и с уникалmными, нашел метод unique, но не знаю как решить с ним задачу.
len(pd.unique(brx['mcc_code'])) > 75
Вот фрагмент данных, строк около миллиона.
mcc_code tr_type amount gender tr_day
946518 6010 7070 11229.58 0.0 439
902107 6010 7070 539019.79 0.0 19
826694 6010 7070 2762.48 1.0 79
799043 4511 6100 103087.53 0.0 52
944055 6010 7070 2021.32 0.0 231
974045 6010 7030 21422.22 1.0 426
930420 6010 7070 28625.99 1.0 414
864425 6010 7070 2515.43 1.0 278
875639 6010 7070 4985.93 1.0 347
803346 6010 7070 6221.19 1.0 18
927200 6010 7070 9107.19 1.0 258
943893 6010 7070 191.58 NaN 124
954317 6010 7030 224591.58 NaN 342
869456 6010 7070 3436.25 1.0 312
534079 6011 7010 22459.16 NaN 438
984953 6010 7071 11645.07 1.0 338
903626 6010 7070 336887.37 1.0 434
814477 6010 7070 44918.32 NaN 404
984236 6010 7071 11858.44 NaN 284
540267 6011 7010 673774.73 0.0 239>
Ответы (3 шт):
Возможно, я не совсем ясно понял задачу, но, вероятно, вам нужно что-то вроде такого решения:
df[df.groupby('tr_day')['mcc_code'].transform('nunique')>75]
размер группы groupby(['tr_day', 'mcc_code']).size() даст количесто уникальных значений 'mcc_code' для каждого дня. чтобы отобрать те, где больше 75, при помощи transform можно положить их в колонку, и отобрать по её значению
df[df.groupby(['tr_day', 'mcc_code'])['mcc_code'].transform('size')>75]
во втором случае вместо 'mcc_code' можно подставить любую существующую колонку
Всем доброго времени суток! Хочу поделиться своим практическим решением данной задачи целиком.
*Task 4: -Выделите из поля tr_datetime относительный день tr_day (первое число до точного времени). -Отфильтруйте строки таким образом, чтобы оставить только те транзакции, у которых в соответствующий относительный день tr_day количество уникальных MCC кодов при транзакциях было больше 75 (можно воспользоваться функцией nunique()) -Сгруппируйте полученный отфильтрованный датафрейм по MCC коду и полу, после чего, пронализировав результат, выберите верные варианты ответов ниже:
- gender == 0 - женщины, gender == 1 - мужчины
- gender == 1 - женщины, gender == 0 - мужчины
- Абсолютное значение медианы с типом "Флористика" (расходов/приходов) у мужчин выше той же медианы у женщин
- Абсолютное значение медианы женских трат (расходов/приходов) на ценные бумаги выше мужских
- Абсолютное значение медианы женских трат (расходов/приходов) в категории "Бары, коктейль-бары, дискотеки, ночные клубы и таверны — места продажи алкогольных напитков" ниже мужских Пояснения: -Для того, чтобы выделить всё, что стоит до первого пробела, можо использовать строковые методы для датафрейма - .str.split(), например. Либо же реализовывать логику выделения подстроки с помощью метода apply. -Понять, какой класс к какому типу транзакций (мужские/женские) относится можно, если поизучать типичные для мужчин/женщин категории и сравнить средние/медианы расходов и/или приходов в них.*
Дилетантским, конечно, способом, но давшим правильный ответ:) (Я начал изучать Питон и решал эту задачу в рамках курса "Python для анализа данных", Сберуниверситет. На ней очень сильно споткнулся...)
`import pandas as pd
import numpy as np
pd.options.display.max_rows = 10`
#закачиваем данные из файлов (сами файлы не привожу, считаю, что они у вас есть)
`customers_gender_train = pd.read_csv("Python And Data Analysis/data/gender_train.csv", sep = ',')
tr_types = pd.read_csv("Python And Data Analysis/data/tr_types.csv", sep = ';')
tr_mcc_codes = pd.read_csv("Python And Data Analysis/data/tr_mcc_codes.csv", sep = ';')
transactions = pd.read_csv("Python And Data Analysis/data/transactions.csv", sep = ',', nrows = 1000000)`
#осуществляем необходимые слияния таблиц (Task 0):
`t = pd.merge(transactions,tr_mcc_codes)
t1 = pd.merge(t,tr_types)
t2 = pd.merge(t1, customers_gender_train, how='left')
t2 #смотрим, что получилось`
#Собственно, решение:
#разбиваем дату-время на отдельные колонки (отделяя их в новую табличку):
`new_t2 = t2['tr_datetime'].str.split(' ',expand=True)
new_t2.columns=['tr_day','tr_time'] #даем колонкам нужные названия
new_t2['tr_day'] = pd.to_numeric(new_t2.tr_day) #делаем колонку tr_day числовой
t2 = pd.concat([t2,new_t2],axis=1) #сливаемся с основной таблицей
t2 #смотрим, что получилось`
#осуществляем необходимую фильтрацию:
g2 = t2.groupby(['tr_day'])
#здесь ТОЛЬКО группируем (разбиваем исходный фрейм на группы; с 'mcc_code' пока ничего не делаем! считать (ПРИМЕНЯТЬ ФУНКЦИЮ) будем потом!
t22 = g2.filter(lambda x: x['mcc_code'].nunique() > 75) #СОЛЬ ЗДЕСЬ!!! :)
#ну а теперь фильтруем ИСХОДНЫЙ фрейм
t2 - ПРИМЕНЯЕМ ФУНКЦИЮ к каждой группе
#- Function to apply to each subframe. Should return True or False. (из pandas.pydata.org - DataFrameGroupBy.filter)
t22 #смотрим, что получилось
#изучаем вручную (в отдельной табличке) мужские и женские mcc_code:
`pd.options.display.max_rows = 1000 t222 = t22.copy()
t222.sort_values(by=['mcc_code','gender'], inplace=True)
t222["abs_amount"] = abs(t222.amount) #абс. значение суммы, т.е. не важно тратили или получали деньги
t222.groupby(['mcc_description','gender']).abs_amount.median() ` #определение пола: 1-мужики (мото,горючее,спирт,дороги...) #0-дамы (секонд, бакалея, ж.одежда...)
#находим ответы на вопросы 3-5:
`pd.options.display.max_rows = 10
t222[t222["mcc_description"].str.contains("Флористика")].groupby(['gender']).amount.median() #3` gender 0.0 -12352.54 1.0 -19090.28 #ДА - 3) Абсолютное значение медианы с типом "Флористика" (расходов/приходов) у мужчин выше той же медианы у женщин
t222[t222["mcc_description"].str.contains("Ценные бумаги")].groupby(['gender']).amount.median() #4
gender
0.0 -6737.75
1.0 -11229.58
#НЕТ - 4) Абсолютное значение медианы женских трат (расходов/приходов) на ценные бумаги выше мужских (Ценные бумаги: брокеры/дилеры)
t222[t222["mcc_description"].str.contains("коктейль-бары")].groupby(['gender']).amount.median() #5
gender
0.0 -9387.93
1.0 -12667.86
#ДА - 5) Абсолютное значение медианы женских трат (расходов/приходов) в категории "Бары, коктейль-бары, дискотеки,
#ночные клубы и таверны — места продажи алкогольных напитков" ниже мужски