Вы можете использовать это:
# groupby and add group sizes
df['id_count'] = df.groupby('id')['id'].transform('size')
# conditions for np.select
conditions = [
(df['id_count'].eq(1) & df['type'].ne('b')),
(df['id_count'].eq(1) & df['type'].eq('b')),
(df['id_count'].ne(1) & df['type'].ne('b')),
(df['id_count'].ne(1) & df['type'].eq('b'))]
# choices for np.select
choices = ['case1', 'case2', 'case3', 'case4']
# Add case column
df['case'] = np.select(conditions, choices, default=None)
# next grouping
grouping = ['id', 'type', 'Date', 'case']
# replace value column
df['value'] = df.groupby(grouping)['value'].transform('sum')
# drop duplicate rows
df = df.drop_duplicates(subset=grouping, keep='first')
# remove extra columns
df = df.drop(['name', 'id_count'], axis='columns')
Шаг за шагом
Прежде всего вы можете создать groupby
столбца id
, например:
gb = df.groupby('id')
Затем вы можете использовать это, чтобы подсчитать, сколько раз происходит id
:
df['id_count'] = gb['id'].transform('size')
df
теперь выглядит так:
id type value Date name id_count
0 111 a 100 2018/11 x1 1
1 112 b 200 2018/12 x2 1
2 113 a 300 2018/08 x3 2
3 113 a 200 2018/08 x4 2
4 114 a 300 2017/12 x4 3
5 114 a 500 2018/12 x5 3
6 114 b 500 2018/12 x5 3
Теперь вы можете использовать np.select
для выполнения ваших условий:
conditions = [
(df['id_count'].eq(1) & df['type'].ne('b')),
(df['id_count'].eq(1) & df['type'].eq('b')),
(df['id_count'].ne(1) & df['type'].ne('b')),
(df['id_count'].ne(1) & df['type'].eq('b'))]
choices = ['case1', 'case2', 'case3', 'case4']
df['case'] = np.select(conditions, choices, default=None)
В результате:
id type value Date name id_count case
0 111 a 100 2018/11 x1 1 case1
1 112 b 200 2018/12 x2 1 case2
2 113 a 300 2018/08 x3 2 case3
3 113 a 200 2018/08 x4 2 case3
4 114 a 300 2017/12 x4 3 case3
5 114 a 500 2018/12 x5 3 case3
6 114 b 500 2018/12 x5 3 case4
Создать еще одну группу с помощью grouping
(список столбцов); затем sum
столбец value
в этих группах, заменив столбец value
.
grouping = ['id', 'type', 'Date', 'case']
df['value'] = df.groupby(grouping)['value'].transform('sum')
В результате:
id type value Date name id_count case
0 111 a 100 2018/11 x1 1 case1
1 112 b 200 2018/12 x2 1 case2
2 113 a 500 2018/08 x3 2 case3
3 113 a 500 2018/08 x4 2 case3
4 114 a 300 2017/12 x4 3 case3
5 114 a 500 2018/12 x5 3 case3
6 114 b 500 2018/12 x5 3 case4
Наконец, drop-duplicates
с использованием списка grouping
, указанного ранее:
df = df.drop_duplicates(subset=grouping, keep='first')
Предоставление:
id type value Date name id_count case
0 111 a 100 2018/11 x1 1 case1
1 112 b 200 2018/12 x2 1 case2
2 113 a 500 2018/08 x3 2 case3
4 114 a 300 2017/12 x4 3 case3
6 114 b 500 2018/12 x5 3 case4
Вы можете удалить дополнительный столбец, используя drop
:
df = df.drop(['name', 'id_count'], axis='columns')