Условие на фрейме данных для создания нового фрейма данных - Python - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть датафрейм, как показано ниже.

    id type  value     Date name
0  111    a    100  2018/11   x1
1  112    b    200  2018/12   x2
2  113    a    300  2018/08   x3
3  113    a    200  2018/08   x4
4  114    a    300  2017/12   x4
5  114    a    500  2018/12   x5
6  114    b    500  2018/12   x5

Я хочу создать фрейм данных на основе 4 условий.

  1. , если идентификатор уникален и введите! = B, затем взять строкуи добавьте столбец case1
  2. , если идентификатор уникален и тип = b, затем возьмите строку, если имя уникально, и добавьте столбец case2
  3. , если идентификатор не уникален, и введите! = b, затем объедините строку с той же датой, суммируязначение, добавьте столбец case3
  4. , если id не уникален и type = b, затем агрегируйте строку с той же датой, суммируя значение, игнорируя строки с типом b, добавьте столбец case4

Новый кадр данных будетбыть следующим:

    id type  value     Date   case
0  111    a    100  2018/11  case1
1  112    b    200  2018/12  case2
2  113    a    500  2018/08  case3
3  114    a    300  2017/12  case4
4  114    b    500  2018/12  case4

Я попытался создать столбец 'case' в качестве первого шага:

для i в df.id.unique ():

if 'b' in df.Type:

    df['Case']= 'case 1'

else:

    df['Case']= 'case 2' else:

else:

if 'b' in df.Type:

    df['Case']= 'case 3'

else:

    df['Case']= 'case 4'

Я новичок в манипуляциях с пандами, поэтому советы будут оценены

1 Ответ

0 голосов
/ 16 ноября 2018

Вы можете использовать это:

# 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')
...