У меня есть следующий фрейм данных:
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)
Но, к сожалению, оба они не вернули правильный ответ. Любые предложения будут очень признательны.
Ответ должен быть примерно таким:
Как 2022/вариант 1.0/бар может быть 3.0?
option содержит значения [0, 0,5, 1] и для этих значений, и я хотел бы подсчитать вхождения этих значений в год столбцов.
@ Адам, извини, неясно, можешь расшифровать номер 3
?
Адам, если у вас есть отзывы о полученном ответе, вам следует использовать комментарии под этим ответом, а не вносить предлагаемые изменения.
3 указывает, что «бар» появляется 3 раза в 2022 году. Для этого я подсчитываю, сколько единиц в столбце 2022 по отношению к «бару»
да, но как же вы агрегируете bar
без учета вариантов?
@Adam Хорошо, я думаю, что понял, но это было не так ясно, пожалуйста, проверьте и дайте мне знать
Предоставленный фрейм данных
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('')
Это возвращает те же результаты, которые я уже получил с обеими командами выше.
По крайней мере, у вас такой же результат, как у меня?
да, у меня те же результаты, что и у вас. Пожалуйста, попробуйте запустить приведенные выше команды.
Я не понимаю, у вас есть 3 вхождения для bar
в 2022 году в вашем результате для варианта 1, если мы ссылаемся на предоставленный фрейм данных? Кажется, есть проблема с ожидаемым результатом в соответствии с предоставленным кадром данных.
Хорошо, я хотел бы рассчитать количество вхождений «bar» и «foo» в каждом году, что означает: если «bar» появляется 2 раза 0,5 в столбце 2022, это означает, что «bar» должно иметь появление 2 раза в столбце 2022 Столбец года 2022. То же самое касается 0 и 1. Это относится и к 'foo'. Когда мы смотрим на столбец 2022, мы можем прочитать, что «foo» имеет 2 раза 0 и один раз 0,5, а «bar» имеет 3 единицы (или 3 появления) в этом столбце.
Последний столбец опций бесполезен и смутил меня. Кроме того, Mozway дает отличный ответ. Как и вы, я только учусь на So. Есть такие умные ребята 8-). Но отличный вопрос.
Используйте 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
С уважением, это отлично, я не знал, как использовать расплав до сих пор. Теперь это сделано.
@LaurentB. Да, очень полезная функция ;)
Какой тогда должен быть правильный ответ? Группа по операции кажется правильной.