#python #pandas #dataframe #series
#python #панды #фрейм данных #Серии
Вопрос:
Я получаю некоторые данные в 11 разных сериях pandas. Мне нужно объединить все данные в один фрейм данных pandas для проведения дальнейшего анализа и составления отчетов.
Формат, в котором принимаются данные, соответствует:
Series1:
Sales
Item Series Year
A Sal 2018 100
2019 200
B Sal 2018 300
2019 400
Series2:
Purchases
Item Series Year
A Pur 2018 50
2019 100
B Pur 2018 150
2019 200
Series3:
Expenses
Product Series Year
A Exp 2019 100
B Exp 2019 200
У меня есть ряд параметров серии. Итак, я создал цикл, в котором следующий код объединяет две из общей серии, пока все серии не будут объединены. Я попытался объединить все такие ряды в один фрейм данных, используя этот код:
df = pd.merge(df,series1,left_on=['Product','Year'],right_on=['Product','Year']).reset_index()
Но даже если мы напишем отдельные строки для каждых двух пар для нашего примера здесь, это будет:
df = pd.merge(series1,series2,left_on=['Product','Year'],right_on=['Product','Year']).reset_index()
df = pd.merge(df,series3,left_on=['Product','Year'],right_on=['Product','Year']).reset_index()
Однако проблема с этим заключается в:
- Это позволяет объединять только две серии одновременно.
- Когда я объединяю третью серию в этом примере, поскольку в ней нет данных за 2018 год, вместо того, чтобы помещать туда NULL, он удаляет строки 2018 даже для данных серий 1 и series 2 в dataframe. Итак, у меня остались только объединенные данные из всех трех серий на 2019 год.
Я рассматривал возможность преобразования всех рядов в список по отдельности, а затем преобразования этих списков в словарь, который затем преобразуется в фрейм данных. Это работает, но требует больших усилий и требует изменения кода при изменении количества серий. Так что у меня это не работает.
Есть ли другой способ сделать это?
Ответ №1:
Вы пробовали использовать этот to_frame
метод?
Например, вы могли бы использовать
df = pd.Series["a", "b", "c"]
df.to_frame()
чтобы преобразовать.
Попробуйте использовать этот метод в вашем фрейме данных.
Вот это в документах.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas .Series.to_frame.html
Комментарии:
1. ДА. Я тоже это пробовал. Но это работает для одной серии за раз. И как только все серии будут индивидуально преобразованы в фреймы данных, я снова не уверен, как приступить к их объединению, учитывая мультииндекс, с которым будет преобразован ряд.
Ответ №2:
Попробуйте pd.concat()
:
import pandas as pd
import pandas as pd
s1 = pd.Series([100, 200, 300, 400], index = pd.MultiIndex.from_arrays([['A','A','B','B'],['1','1','2','2'], [2018, 2019, 2018, 2019]]))
s2 = pd.Series([50, 100, 150, 200], index = pd.MultiIndex.from_arrays([['A','A','B','B'],['3','3','4','4'], [2018, 2019, 2018, 2019]]))
s3 = pd.Series([100, 200], index = pd.MultiIndex.from_arrays([['A','B'],['5','6'], [2019, 2019]]))
df = pd.concat([s.droplevel(1) for s in [s1, s2, s3]], axis = 1)
0 1 2
A 2018 100 50 NaN
2019 200 100 100.0
B 2018 300 150 NaN
2019 400 200 200.0
Комментарии:
1. Привет, Ли. Спасибо за ответ. Это точно работает, но мои данные имеют дополнительный индекс, как указано в вопросе (называемый Series в вопросе), который изменяется для каждой серии pandas. Из-за этого, когда я запускаю concat, для меня выходные данные дублируются для каждой серии с помощью NaN везде. Я вижу, что мы можем игнорировать индекс в concat, но можем ли мы что-то сделать, чтобы игнорировать только второй из трех индексов в многоиндексированном ряду? Или, может быть, удалить второй индекс перед объединением?
2. Да, вы могли бы удалить второй индекс перед объединением. Пожалуйста, ознакомьтесь с обновленным ответом.
3. Эй, спасибо за это. Здесь я столкнулся с другой проблемой. Многие серии содержат данные с различного уровня 3. Таким образом, в многоиндексном уровне 3 данные имеют много вариаций. Это приводит к созданию фрейма данных, который имеет много значений NaN. Я подумал, что если вместо того, чтобы хранить каждую серию в виде столбцов в dataframe, если я сделаю два столбца для первого уровня (A и B), сохраню второй уровень (год) в индексе и сделаю название серии индексом в dataframe, чтобы показывать значения в столбце A или B. Возможно ли это? Как это сделать?