#python #pandas #dataframe #jupyter-notebook
#питон #панды #фрейм данных #jupyter-записная книжка #python #pandas #jupyter-ноутбук
Вопрос:
Я хочу объединить два фрейма данных с неравной длиной с некоторыми условиями. Сведения о фреймах данных следующие:
- Фрейм данных A содержит приблизительно 1000 строк
- Фрейм данных B содержит приблизительно 50 строк
Поля в обоих фреймах данных похожи, как в:
A_Name, A_count, A_Normalised value, A_year
Фрейм данных A:
print (df1)
A_Organisation A_count A_Normalised A_Year
0 ABC 654 34545 2018
1 DEF 565 54564 2018
2 GHI 565 34546 2018
3 QWE 790 3945 2018
4 DSO 788 1561 2017
5 DFB 34579 546 2017
6 HHS 56 31651 2017
7 FDGH 98 156 2016
8 DSFH 51651 153156 2016
9 KBIU 151 1561 2015
10 SDF 165 6513 2015
Для фрейма данных B:
B_Name, B_count, B_Normalised value, B_year
print (df2)
B_Organisation B_count B_Normalised B_Year
0 MNO 123 432 2018
1 MNO 133 234 2018
2 MNO 8743 484 2017
3 MNO 1335 1512 2015
4 MNO 456 3454 2014
5 MNO 345 234 2014
Теперь я хочу объединить оба фрейма данных на основе year, но мне не нужны повторяющиеся значения.
т.е. если в фрейме данных A, скажем, за 2018 год, содержится 50 значений, а в фрейме данных B, за 2018 год, содержится 5 значений. Тогда общее количество строк за 2018 год должно быть 50, а выходные данные должны быть такими:
Комментарии:
1. Вы показали выходные данные, но соответствующий ввод также был бы весьма полезен.
2. объединение только в year создаст отношение «многие ко многим», где каждая строка в любом фрейме данных будет соответствовать нескольким строкам по обе стороны от объединения и умножит ваши результаты. Вам потребуется объединить несколько критериев, чтобы удалить дубликаты
Ответ №1:
Используйте GroupBy.cumcount
для столбцов счетчика, затем DataFrame.merge
со rename
столбцами, чтобы избежать столбцов с одинаковым содержимым A_Year
и B_Year
, если используются параметры left_on
и right_on
в merge
:
df1['g'] = df1.groupby('A_Year').cumcount()
df2['g'] = df2.groupby('B_Year').cumcount()
df = (df1.rename(columns={'A_Year':'Year'})
.merge(df2.rename(columns={'B_Year':'Year'}), on=['Year','g'], how='outer')
.drop('g', axis=1))
print (df)
A_Organisation A_count A_Normalised Year B_Organisation B_count
0 ABC 654.0 34545.0 2018 MNO 123.0
1 DEF 565.0 54564.0 2018 MNO 133.0
2 GHI 565.0 34546.0 2018 NaN NaN
3 QWE 790.0 3945.0 2018 NaN NaN
4 DSO 788.0 1561.0 2017 MNO 8743.0
5 DFB 34579.0 546.0 2017 NaN NaN
6 HHS 56.0 31651.0 2017 NaN NaN
7 FDGH 98.0 156.0 2016 NaN NaN
8 DSFH 51651.0 153156.0 2016 NaN NaN
9 KBIU 151.0 1561.0 2015 MNO 1335.0
10 SDF 165.0 6513.0 2015 NaN NaN
11 NaN NaN NaN 2014 MNO 456.0
12 NaN NaN NaN 2014 MNO 345.0
B_Normalised
0 432.0
1 234.0
2 NaN
3 NaN
4 484.0
5 NaN
6 NaN
7 NaN
8 NaN
9 1512.0
10 NaN
11 3454.0
12 234.0