Как запустить цикл внутри фрейма данных Pandas для добавления столбца?

#python #python-2.7 #pandas

#python #python-2.7 #pandas

Вопрос:

У меня есть фрейм данных, который выглядит следующим образом:

     MID        POSITION
1   22596394       R8

2   22596394       R8 

3   22596394       R8

4   22591549       R6

5   22591549       R6

6   22591549       R6
  

Теперь у меня есть другой фрейм данных, который будет выводиться после выполнения некоторого кода, который будет выглядеть следующим образом:

 Position     Usage
R1             0  
R2             0 
R3             0
R4             0
R5             0
R6             1
R7             0 
R8             1
L1             0
L2             0
L3             0 
...           
L8             0
  

Я хотел бы заполнить столбец использования в соответствии с приведенной ниже логикой:

Где бы ни происходили изменения MID, обратите внимание на соответствующую позицию и заполните строку использования, соответствующую в выходном фрейме данных, например: в приведенном выше фрейме данных строки использования R8 и R6 должны быть заполнены 1, а столбцы остальных позиций — 0. Аналогично, если MID дважды изменяется для одной и той же позиции, скажем, R6, например, строка использования R6 должна быть заполнена 2 и так далее. Какой был бы лучший способ сделать это? Заранее спасибо!

Комментарии:

1. Можете ли вы добавить желаемый результат из ввода?

2. Я обновил выходной фрейм данных. Чтобы сделать это более понятным, предположим, что MID менялся 2 раза, когда позиции все еще были, скажем, R6. Затем строка использования, соответствующая R6, должна быть заполнена 2 и так далее. Спасибо!

3. Хммм, но ‘MID’ не изменяется ни в R6 , ни в R8 . Это в 3 раза больше одного и того же значения.

4. Извините, я не могу выразиться ясно. Допустим, скорее MID должен быть уникальным, и позиция отмечена. Например, в приведенной выше таблице использование R6 и R8 равно 1, потому что оно имеет только один уникальный MID. Надеюсь, это прояснит.

Ответ №1:

Я думаю, вам нужно nunique и затем reindex :

 print (df1.groupby('POSITION')['MID'].nunique())
POSITION
R6    1
R8    1
Name: MID, dtype: int64

print (df1.groupby('POSITION')['MID']
          .nunique()
          .reindex(df2.set_index('Position').index, fill_value=0)
          .rename('Usage')
          .reset_index())
   Position  Usage
0        R1      0
1        R2      0
2        R3      0
3        R4      0
4        R5      0
5        R6      1
6        R7      0
7        R8      1
8        L1      0
9        L2      0
10       L3      0
  

Объяснение:

Для получения количества уникальных значений для каждой группы необходимо groupby по столбцу POSITION , а затем объединить nunique по столбцу MID . Вы получаете new Series с индексами R6 и R8 . Затем нужно добавить другие значения из df2 и столбца Position . Итак, если значения уникальны, одним из возможных решений является создание index из столбца position с помощью set_index , а затем reindex значений в index из df1 index через df2 из в,. Получите некоторые NaN , которые заменяются на 0 (параметр fill_value=0 ). Затем нужно создать новый столбец из индекса — сначала переименовать Series имя на rename и последнее reset_index — получить хорошее DataFrame .

Комментарии:

1. Разве это не должно быть Usage вместо Position в (df2.set_index(‘Position’).index, fill_value=0), учитывая, что я хочу заполнить столбец Usage?

2. Работает как обычно. Еще раз спасибо!

3. Рад, что могу вам помочь! Хороший день!

4. Я не думаю, что вы хотите nunique что-то более похожее (df.POSITION[1:][~(df.MID.shift(1) == df.MID)[1:]]) , учитывая ваше описание. Вам нужна соответствующая позиция при изменении MID… по крайней мере, это то, что вы описали сначала, но потом вы сказали что-то об уникальности…

5. Скорее, что-то вроде: (df.POSITION[1:][~(df.MID.shift(1) == df.MID)[1:]]).value_counts().reindex(['R1','R2','R3','R4','R5','R6'], fill_value=0) или используйте хитрый index трюк, который Израэль использовал в этом ответе.