#python #pandas #dataframe #data-analysis #data-cleaning
#python #pandas #фрейм данных #анализ данных #очистка данных
Вопрос:
У меня есть набор данных из нескольких таблиц. Некоторые поля перекрываются, но в некоторых таблицах они могут иметь отношение «один ко многим», в то время как в других таблицах они могут иметь отношение «один к одному». Я пытаюсь создать новый фрейм данных, где я могу принимать значения, связанные с одним полем (один к одному), и значения, связанные с этим же полем, но в другой таблице (один ко многим), и все они перечислены в новом фрейме данных (один ко многим).
Один фрейм данных:
finishtId eventId instanceId ... value statusId finishType
0 1 18 1 ... 218.3 1 Positive
1 2 18 2 ... 217.586 1 Positive
2 3 18 3 ... 216.719 1 Positive
3 4 18 4 ... 215.464 1 Positive
4 5 18 5 ... 218.385 1 Negative
Другой фрейм данных:
eventId instanceId red blue time duration milliseconds
0 841 153 1 1 17:05:23 26.898 26898
1 841 30 1 1 17:05:52 25.021 25021
2 841 17 1 11 17:20:48 23.426 23426
3 841 4 1 12 17:22:34 23.251 23251
4 841 13 1 13 17:24:10 23.842 23842
5. 841. 153. 2 45. 17:45:30. 24.786. 26473
... ... ... ... ... ... ...
7633 1036 822 2 48 16:20:38 22.143 22143
7634 1036 1 2 50 16:23:05 21.853 21853
7635 1036 849 2 49 16:24:00 22.475 22475
7636 1036 154 2 62 16:42:16 24.010 24010
7637 1036 822 3 64 16:42:47 22.607 22607
Я хочу создать новый фрейм данных, который добавляет все значения из dataframe2 (красное, синее, время, длительность, миллисекунды) в поля InstanceID и EventID, чтобы dataframe1 показывал отношения «один ко многим». Также я хочу создать новое поле, которое сообщает мне, сколько красных для каждого InstanceID и EventID (numRed), в основном, что-то вроде этого:
eventId instanceId red numRed blue ... time duration value statusId finishType
0 841 153 1 2 17 ... 17:05:23 26.898 218.3 1 Positive
1 841 153 2 2 52 ... 17:45:30 24.786 217.586 1 Positive
1 841 146 1 1 40 ... 17:32:30 24.986 217.586 1 Negative
Таким образом, по существу, каждый красный, синий, time, duration, value, StatusID и finishType перечислены для каждого InstanceID для каждого EventID. Я новичок в Pandas, поэтому я копался в функциях, но я продолжаю получать ошибки, обычно связанные с типом данных (float vs str) и т.д…
ОБНОВЛЕНИЕ: После получения решения от Edunne я понял, что то, что, по моему мнению, будет лучше работать для dataset, на самом деле является чем-то другим. Я бы предпочел вместо этого объединить строки с «красными» значениями для каждого «InstanceID» для каждого «EventID». Разные значения будут усреднены, поэтому среднее значение полей «длительность» и среднее значение полей «значение». Что-то вроде этого:
eventId instanceId numRed ... duration value statusId finishType
0 841 153 2 ... 25.842 218.3 1 Positive
1 841 146 1 ... 24.986 217.586 1 Negative
Комментарии:
1. Вы не должны задавать вопрос, получать ответ, а затем говорить, что вам нужно что-то еще. Если ответ является решением вашей проблемы, как указано изначально, примите его. Задайте новый вопрос о вашей новой проблеме.
Ответ №1:
Вы должны показать нам, что вы пробовали! Людям проще отвечать.
Хотя я бы подошел к этому с помощью слияния Pandas. Что-то вроде:
new_df = df2.merge(df1, on=["eventID", "instanceId"], how="outer")
new_df будет содержать все строки в df2 и любые совпадающие строки из df2.
Вы можете столкнуться с проблемой, если типы данных для «EventID» или «InstanceID» различаются в двух фреймах данных, но это должно быть достаточно легко устранить…
Редактировать Вероятно, ищете group_by . Вы должны выполнить агрегацию для второго фрейма данных перед объединением с другим.
# Dictionary with keys as column names and values as the aggregation/summary method.
agg_dict = {
"duration": "mean",
"value": "mean"
}
group_by_columns = ["eventID", "instanceId"] # We'll get one row in output for each combination of these columns
new_df2 = df2.groupby(group_by_columns).agg(agg_dict).reset_index()
result = new_df2.merge(df1, on=["eventID", "instanceId"], how="outer")
Дайте мне знать, как это происходит!
Комментарии:
1. Спасибо! Это было именно то, что я искал. Единственная проблема в том, что теперь, когда я вижу результат, я ищу что-то другое :). Поэтому вместо того, чтобы перечислять каждое значение ‘red’ для каждого ‘InstanceID’ для каждого ‘EventID’, я хочу просто сохранить значение ‘numRed’ и найти среднее значение ‘duration’ и среднее значение ‘value’ для тех, которые имеют более 1 значения ‘red’. По сути, объединить их в 1 строку.
2. Вот результат: ошибка спецификации: вложенный переименователь не поддерживается
3. Можете ли вы предоставить свой код для agg_dict? Это ошибка, которую вы получаете, когда у вас есть столбец в agg_dict, который не существует в dataframe
4. Извините, это была опечатка с моей стороны. Я все еще получаю ошибку, но это связано с типом данных: DataError: нет числовых типов для агрегирования должен ли я выполнить df2.loc[‘duration’]= float()
5. Не беспокойтесь. Для изменения типов данных я бы выбрал
df2["duration"] = pd.to_numeric(df2["duration"])