#python #excel #pandas #dataframe
#python #excel #pandas #dataframe
Вопрос:
Я подумываю об использовании pandas для объединения нескольких повторяющихся строк «Ocode» и «Ccode». В идеале мне нужен только один «Ocode» или «Ccode» на строку. При наличии повторяющихся дат в c # # (например, c21) сохраняется только последняя дата. Отдельные даты в разных столбцах с одинаковым «Ocode» /»Ccode» также должны быть объединены.
(Для справочных целей: код O и C соответственно представляет код организации и код корпорации.)
Это заголовок фрейма данных.
Num Ocode Ccode c21 c57 c58 c59 c70 c71 c74 c75
0 BK0001000 NaN NaN NaN NaN NaN NaN NaN NaN 2021-02-09
1 CU0030000 NaN NaN NaN NaN NaN NaN 2021-12-31 NaN NaN
2 CU0030000 NaN NaN NaN NaN NaN NaN 2021-12-31 NaN NaN
3 CU0048000 NaN NaN NaN 2018-06-19 NaN NaN NaN NaN NaN
4 CU0056000 NaN NaN NaN NaN NaN NaN NaN 2020-06-04 NaN
... ... ... ... ... ... ... ... ... ... ...
2384 NaN CU0280002 2017-12-31 NaN NaN NaN NaN NaN NaN NaN
2385 NaN CU0280002 2016-12-31 NaN NaN NaN NaN NaN NaN NaN
2386 NaN CU0280002 NaN NaN NaN NaN NaN NaN 2017-12-31 NaN
2387 NaN CU0659001 NaN NaN NaN NaN NaN NaN 2022-05-31 NaN
Который должен стать —->
Num Ocode Ccode c21 c57 c58 c59 c70 c71 c74 c75
0 BK0001000 NaN NaN NaN NaN NaN NaN NaN NaN 2021-02-09
1 CU0030000 NaN NaN NaN NaN NaN NaN 2021-12-31 NaN NaN
3 CU0048000 NaN NaN NaN 2018-06-19 NaN NaN NaN NaN NaN
4 CU0056000 NaN NaN NaN NaN NaN NaN NaN 2020-06-04 NaN
... ... ... ... ... ... ... ... ... ... ...
2384 NaN CU0280002 2017-12-31 NaN NaN NaN NaN NaN 2017-12-31 NaN
2387 NaN CU0659001 NaN NaN NaN NaN NaN NaN 2022-05-31 NaN
Попытка:
import os
import xlsxwriter
import pandas as pd
import numpy as np
# Pandas and XR
df = pd.read_excel('Result - Company.xlsx')
#ic = 'c21'#IndustryCode
ic = 'c57'
#ic = 'c58'
#ic = 'c59'
#ic = 'c70'
#ic = 'c71'
#ic = 'c74'
#ic = 'c75'
df[ic] = pd.to_datetime(df[ic]) # , errors='coerce'
df = df.sort_values(ic).drop_duplicates('Ccode', keep='last')
и выполните слияние один за другим. Однако этот метод имеет тенденцию удалять информацию в другом столбце при работе с одним из столбцов c # # (т.Е. c21)
df.to_excel(ic ‘.xlsx’, index=False)
Комментарии:
1. Если
Ocode
существует, тоCcode
всегда NaN? ЕслиCcode
существует, тоOcode
всегда NaN?2. Бывают случаи, когда оба существуют, но в этом случае Ccode можно удалить и сохранить Ocode только для простоты.
3. Ответ был отредактирован
EDIT
Ответ №1:
Одна из идей заключается в группировании по обоим столбцам с заменой NaN
, чтобы избежать удаления этих групп в более старых версиях pandas с GroupBy.last
помощью для последних не пропущенных значений для групп:
df = (df.assign(Ocode = df['Ocode'].fillna('nan'),Ccode = df['Ccode'].fillna('nan'))
.groupby(['Ocode','Ccode'])
.last()
.reset_index()
.replace({'Ocode': {'nan':np.nan}, 'Ccode':{'nan':np.nan}}))
Для последних версий pandas:
df = (df.groupby(['Ocode','Ccode'])
.last()
.reset_index())
print (df)
Ocode Ccode c21 c57 c58 c59 c70 c71
0 BK0001000 NaN NaN NaN NaN NaN NaN NaN
1 CU0030000 NaN NaN NaN NaN NaN NaN 2021-12-31
2 CU0048000 NaN NaN NaN 2018-06-19 NaN NaN NaN
3 CU0056000 NaN NaN NaN NaN NaN NaN NaN
4 NaN CU0280002 2016-12-31 NaN NaN NaN NaN NaN
5 NaN CU0659001 NaN NaN NaN NaN NaN NaN
c74 c75
0 NaN 2021-02-09
1 NaN NaN
2 NaN NaN
3 2020-06-04 NaN
4 2017-12-31 NaN
5 2022-05-31 NaN
Редактировать:
Решение выше протестируйте комбинацию обоих столбцов, если необходимо установить приоритет Ocode
, это означает, что установлено NaN
Ccode
значение, если существуют оба варианта использования перед решением выше:
df.loc[df['Ocode'].notna() amp; df['Ocode'].notna(), 'Ccode'] = np.nan
РЕДАКТИРОВАНИЕ 1: одна идея, обрабатывающая оба кода отдельно:
df1 = (df.assign(Ocode = df['Ocode'].fillna('nan'))
.drop('Ccode', axis=1)
.groupby('Ocode')
.last()
.reset_index())
df2 = (df.assign(Ccode = df['Ccode'].fillna('nan'))
.drop('Ocode', axis=1)
.groupby('Ccode')
.last()
.reset_index())
both = (pd.concat([df1, df2], sort=False)
.replace({'Ocode': {'nan':np.nan}, 'Ccode':{'nan':np.nan}}))
Комментарии:
1. Я столкнулся с проблемой, когда он сохранял только строки, в которых были как Ocode, так и Ccode, и удалил все остальное.
2. Мне удалось решить проблему, выполнив это дважды для Ocode и Ccode отдельно. Спасибо!