#python #pandas
#python #панды
Вопрос:
У меня есть такой фрейм данных, как . df = pd.DataFrame({'ID':[1,1,2,2,3,3,4,4,5,5,5],'Col1':['Y','Y','Y','N','N','N','Y','Y','Y','N','N']})
Что я хотел бы сделать, это сгруппировать по столбцу ‘ID’, а затем получить статистику по трем условиям:
- Сколько групп имеют только ‘Y
- Сколько групп имеют не менее 1 ‘Y’ и не менее 1 ‘N’
- Сколько групп имеют только ‘N
groups = df.groupby('ID') groups.Col1.value_counts()
дает мне визуальное представление о том, что я ищу, но как я могу затем перебирать результаты метода value_counts() для проверки этих условий?
Ответ №1:
Я думаю pd.crosstab()
, может быть более подходящим для вашего варианта использования.
Код
df_crosstab = pd.crosstab(df["ID"], df["Col1"])
Col1 N Y
ID
1 0 2
2 1 1
3 2 0
4 0 2
5 2 1
Groupby также может выполнять эту работу, но гораздо более утомительно:
df_crosstab = df.groupby('ID')["Col1"]
.value_counts()
.rename("count")
.reset_index()
.pivot(index="ID", columns="Col1", values="count")
.fillna(0)
Фильтрация групп
После создания df_crosstab
можно легко создать фильтры для ваших 3 вопросов:
# 1. How many groups have only 'Y's
df_crosstab[df_crosstab['N'] == 0]
Col1 N Y
ID
1 0 2
4 0 2
# 2. How many groups have at least 1 'Y' and at least 1 'N'
df_crosstab[(df_crosstab['N'] > 0) amp; (df_crosstab['Y'] > 0)]
Col1 N Y
ID
2 1 1
5 2 1
# 3. How many groups have only 'N's
df_crosstab[df_crosstab['Y'] == 0]
Col1 N Y
ID
3 2 0
Если вам нужно только количество групп, просто возьмите длину отфильтрованного фрейма данных перекрестной таблицы. Я считаю, что это также значительно упрощает автоматизацию.
Комментарии:
1. Спасибо, что поделились хорошим ответом с хорошим объяснением.
Ответ №2:
groups = df.groupby('ID')
answers = groups.Col1.value_counts()
for item in answers.iteritems():
print(item)
То, что вы создаете, — это серия, из value_counts()
которой вы можете перебирать их. Обратите внимание, что это не то, что вы хотите. Вам нужно будет проверить каждый из этих элементов на наличие тестов, которые вы ищете.
Ответ №3:
Если вы группируете по ‘ID’ и используете функцию ‘sum’, у вас будут все буквы в одной строке для каждой группы. Затем вы можете просто посчитать строки, чтобы проверить свои условия, и взять их суммы, чтобы узнать точные числа для всех групп:
strings = df.groupby(['ID']).sum()
only_y = sum(strings['Col1'].str.count('N') == 0)
only_n = sum(strings['Col1'].str.count('Y') == 0)
both = sum((strings['Col1'].str.count('Y') > 0) amp; (strings['Col1'].str.count('N') > 0))
print('Number of groups with Y only: ' str(only_y),
'Number of groups with N only: ' str(only_n),
'Number of groups with at least one Y and one N: ' str(both),
sep='n')