#python #pandas #dataframe
Вопрос:
У меня есть следующий фрейм данных:
ID | event_1_positive | событие_2_негативное | event_3_neutral | event_4_negative | event_5_positive |
---|---|---|---|---|---|
1 | 1 | 1 | 0 | 1 | 0 |
2 | 1 | 0 | 0 | 0 | 1 |
3 | 0 | 1 | 1 | 1 | 0 |
4 | 1 | 1 | 0 | 0 | 0 |
5 | 0 | 0 | 1 | 1 | 1 |
6 | 0 | 1 | 1 | 0 | 1 |
7 | 1 | 1 | 1 | 0 | 0 |
8 | 0 | 1 | 0 | 0 | 0 |
9 | 1 | 1 | 1 | 1 | 0 |
10 | 0 | 0 | 0 | 0 | 1 |
Что я хотел бы сделать, так это упорядочить события по их эффекту (положительному, отрицательному или нейтральному) и вернуть количество для каждого эффекта.
В этом случае мой ожидаемый результат будет:
0 negative 11
1 positive 9
2 neutral 5
Комментарии:
1. Знаете ли вы, когда появится отрицательный столбец, а когда появится положительный? или они могут быть случайными?
2. Они будут случайными.
Ответ №1:
Используйте filter
и groupby
:
>>> df.filter(like='event')
.groupby(lambda x: x.rsplit('_', 1)[1], axis=1)
.sum().sum()
negative 11
neutral 5
positive 9
dtype: int64
Ответ №2:
Вы можете создать новые столбцы, в которые вы добавляете все столбцы с похожими эффектами, например df["negative"] = df["event_2_negative"] df["event_4_negative"]
, а затем удалить другие столбцы, а затем выполнить df["negative"].value_counts()
, например, или df["negative"].sum()
Ответ №3:
Это редкий случай, когда учет в цикле кажется практичным, поскольку существует управляемое количество столбцов
# start a dictionary to pack with results
categories = {k: 0 for k in ("negative", "positive", "neutral")}
for colname in df: # dataframes are iterable by-column name!
if "_" not in colname:
continue # or consider alerting on this condition
for category in categories.keys():
if category in colname: # substring compare
categories[category] = df[colname].sum()
break # successfully found category -> next colname
else: # didn't find and break
raise ValueError(f"no category for {colname}")
# create a collection of results
df_results = pd.Series(categories).to_frame().reset_index()
index 0
0 negative 11
1 positive 9
2 neutral 5
Ответ №4:
Одним из вариантов является изменение формы данных, когда у вас есть все отрицательные значения в одном столбце, одинаковые для положительных и нейтральных значений. У ваших столбцов есть шаблон (некоторые заканчиваются положительными значениями, некоторые столбцы заканчиваются нейтральными, …).
Мы можем использовать этот шаблон в pivot_longer из pyjanitor для изменения формы данных, а затем агрегирования (уменьшения):
# pip install git https://github.com/pyjanitor-devs/pyjanitor.git
import pandas as pd
import janitor
(df.pivot_longer(index='ID',
names_to=('positive', 'negative', 'neutral'),
names_pattern=('positive', 'negative', 'neutral'))
.iloc[:, 1:]
.sum()
)
positive 9.0
negative 11.0
neutral 5.0
dtype: float64
Ответ №5:
df.
drop("ID", axis=1).
rename(columns=lambda x: x.split("_")[2]).
unstack().
droplevel(1).
reset_index().
groupby("index").
sum()
# 0
# index
# negative 11
# neutral 5
# positive 9