Чтобы подсчитать количество вхождений каждого года для каждого «варианта» и «типа»,

У меня есть следующий фрейм данных:

d_f = pd.DataFrame({
'Type': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
'count': ['one', 'one', 'two', 'two', 'one', 'one'],
2022: [0, 0, 0.5, 1, 1, 1],
2023: [0, 0.5, 0.5, 1, 1, 1],
2024: [0.5, 0.5, 1, 1, 0, 0],
2025: [1, 0, 0.5, 0.5, 1, 1],
2026: [0, 0.5, 1, 1, 0, 0.5],
'option': [0, 1, 0, 0.5, 1, 0.5]})     

Я пытаюсь подсчитать количество вхождений каждого года для каждого «варианта» в соответствии со значениями в «Типе».

Я использовал следующий код:

table = d_f.pivot_table(index=['Type'], columns='option',aggfunc='count'
                                            ).fillna(0)
table

и это тоже:

table = d_f.groupby(['option', 'Type'])[2022, 2023, 2024, 2025, 2026].count()
table = table.unstack(level=0).fillna(0)

Но, к сожалению, оба они не вернули правильный ответ. Любые предложения будут очень признательны.

Ответ должен быть примерно таким:

Какой тогда должен быть правильный ответ? Группа по операции кажется правильной.

rafaelc 17.02.2023 18:10

Как 2022/вариант 1.0/бар может быть 3.0?

mozway 17.02.2023 18:27

option содержит значения [0, 0,5, 1] ​​и для этих значений, и я хотел бы подсчитать вхождения этих значений в год столбцов.

Adam 17.02.2023 18:31

@ Адам, извини, неясно, можешь расшифровать номер 3?

mozway 17.02.2023 18:35

Адам, если у вас есть отзывы о полученном ответе, вам следует использовать комментарии под этим ответом, а не вносить предлагаемые изменения.

Henry Ecker 17.02.2023 18:37

3 указывает, что «бар» появляется 3 раза в 2022 году. Для этого я подсчитываю, сколько единиц в столбце 2022 по отношению к «бару»

Adam 17.02.2023 18:37

да, но как же вы агрегируете bar без учета вариантов?

Laurent B. 17.02.2023 18:48

@Adam Хорошо, я думаю, что понял, но это было не так ясно, пожалуйста, проверьте и дайте мне знать

mozway 17.02.2023 18:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
8
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Предоставленный фрейм данных

d_f
  Type count  2022  2023  2024  2025  2026  option
0  foo   one   0.0   0.0   0.5   1.0   0.0     0.0
1  foo   one   0.0   0.5   0.5   0.0   0.5     1.0
2  foo   two   0.5   0.5   1.0   0.5   1.0     0.0
3  bar   two   1.0   1.0   1.0   0.5   1.0     0.5
4  bar   one   1.0   1.0   0.0   1.0   0.0     1.0
5  bar   one   1.0   1.0   0.0   1.0   0.5     0.5
import pandas as pd

d_f = pd.DataFrame({
'Type': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
'count': ['one', 'one', 'two', 'two', 'one', 'one'],
2022: [0, 0, 0.5, 1, 1, 1],
2023: [0, 0.5, 0.5, 1, 1, 1],
2024: [0.5, 0.5, 1, 1, 0, 0],
2025: [1, 0, 0.5, 0.5, 1, 1],
2026: [0, 0.5, 1, 1, 0, 0.5],
'option': [0, 1, 0, 0.5, 1, 0.5]})

table = d_f.groupby(['option', 'Type']).nunique().drop('count', axis=1)
table = table.unstack(level=0).fillna('')

print(d_f)
table
       2022           2023           2024  ...      2025           2026          
option  0.0  0.5  1.0  0.0  0.5  1.0  0.0  ...  1.0  0.0  0.5  1.0  0.0  0.5  1.0
Type                                       ...                                   
bar          1.0  1.0       1.0  1.0       ...  1.0       2.0  1.0       2.0  1.0
foo     2.0       1.0  2.0       1.0  2.0  ...  1.0  2.0       1.0  2.0       1.0

[2 rows x 15 columns]

Для наглядности я использовал fillna('')

Это возвращает те же результаты, которые я уже получил с обеими командами выше.

Adam 17.02.2023 18:38

По крайней мере, у вас такой же результат, как у меня?

Laurent B. 17.02.2023 18:40

да, у меня те же результаты, что и у вас. Пожалуйста, попробуйте запустить приведенные выше команды.

Adam 17.02.2023 18:41

Я не понимаю, у вас есть 3 вхождения для bar в 2022 году в вашем результате для варианта 1, если мы ссылаемся на предоставленный фрейм данных? Кажется, есть проблема с ожидаемым результатом в соответствии с предоставленным кадром данных.

Laurent B. 17.02.2023 18:45

Хорошо, я хотел бы рассчитать количество вхождений «bar» и «foo» в каждом году, что означает: если «bar» появляется 2 раза 0,5 в столбце 2022, это означает, что «bar» должно иметь появление 2 раза в столбце 2022 Столбец года 2022. То же самое касается 0 и 1. Это относится и к 'foo'. Когда мы смотрим на столбец 2022, мы можем прочитать, что «foo» имеет 2 раза 0 и один раз 0,5, а «bar» имеет 3 единицы (или 3 появления) в этом столбце.

Adam 17.02.2023 18:58

Последний столбец опций бесполезен и смутил меня. Кроме того, Mozway дает отличный ответ. Как и вы, я только учусь на So. Есть такие умные ребята 8-). Но отличный вопрос.

Laurent B. 17.02.2023 19:33

Используйте concat и простой groupby + value_counts

>>> pd.concat([d_f.groupby('Type')[year].value_counts()
               for year in [2022, 2023, 2024, 2025, 2026]], axis=1).fillna(0)

          2022  2023  2024  2025  2026
Type                                  
bar  0.0   0.0   0.0   2.0   0.0     1
     0.5   0.0   0.0   0.0   1.0     1
     1.0   3.0   3.0   1.0   2.0     1
foo  0.0   2.0   1.0   0.0   1.0     1
     0.5   1.0   2.0   2.0   1.0     1
     1.0   0.0   0.0   1.0   1.0     1
Ответ принят как подходящий

IIUC, вы хотите что-то вроде:

(d_f.drop(columns='option')
    .melt(['Type', 'count'], var_name='year', value_name='option')
    .groupby(['Type', 'year', 'option'])['option'].count()
    .unstack('year', fill_value=0).unstack('option', fill_value=0)
)

Или:

df2 = (d_f.drop(columns='option')
          .melt(['Type', 'count'], var_name='year', value_name='option')
      )

out = pd.crosstab(df2['Type'], [df2['year'], df2['option']])

Выход:

year   2022         2023         2024         2025         2026        
option  0.0 0.5 1.0  0.0 0.5 1.0  0.0 0.5 1.0  0.0 0.5 1.0  0.0 0.5 1.0
Type                                                                   
bar       0   0   3    0   0   3    2   0   1    0   1   2    1   1   1
foo       2   1   0    1   2   0    0   2   1    1   1   1    1   1   1

С уважением, это отлично, я не знал, как использовать расплав до сих пор. Теперь это сделано.

Laurent B. 17.02.2023 19:28

@LaurentB. Да, очень полезная функция ;)

mozway 17.02.2023 19:33

Другие вопросы по теме