Выборочное умножение элементов кадра данных на число на основе соответствия между индексом и столбцами - PullRequest
1 голос
/ 17 апреля 2020

Предположим, у нас есть фрейм данных df измерения nxn с двумя разными уровнями индекса, одинаковыми для строк и столбцов. Мне нужно выборочно умножить некоторые элементы df на основе соответствия между индексом строк и индексом столбцов.

вот пример, чтобы прояснить вопрос:

df = pd.DataFrame(np.ones((5,5)), index=[['A','A','B','B','C'], [1,2,1,2,1]], columns=[['A','A','B','B','C'], [1,2,1,2,1]])

сейчас Я хочу умножить элементы в df следующим образом:

  • , если индекс и столбцы идентичны, умножить относительные элементы на 1 (например, A1 и A1);

  • , если внешний индекс равен внешнему столбцу, но внутренний индекс отличается от внутреннего столбца, умножьте относительные элементы на 2 (например, A1 и A2);

  • если внешний индекс отличается от внешнего столбца, но внутренний индекс равен внутреннему столбцу, умножьте относительные элементы на 3 (например, B1 и A1);

  • , если внешний индекс отличается от внешнего столбца, а внутренний индекс отличается от внутреннего столбца, умножьте относительные элементы на 4 (например, А2 и С1);

ожидаемый результат должен быть кадром данных, содержащим народ задолженные элементы:

     A A B B C
     1 2 1 2 1

A 1  1 2 3 4 3
A 2  2 1 4 3 4
B 1  3 4 1 2 3
B 2  4 3 2 1 4
C 1  3 4 3 4 1

Ответы [ 2 ]

3 голосов
/ 17 апреля 2020

Это скорее руководство, но оно подойдет:

offsets = [i + (df.columns.get_level_values(i).values[:,None] != df.index.get_level_values(i).values)
           for i in range(2)]

# output:
df.mul(offsets[0]*2 + offsets[1])

Вывод:

       A         B         C
       1    2    1    2    1
A 1  1.0  2.0  3.0  4.0  3.0
  2  2.0  1.0  4.0  3.0  4.0
B 1  3.0  4.0  1.0  2.0  3.0
  2  4.0  3.0  2.0  1.0  4.0
C 1  3.0  4.0  3.0  4.0  1.0
2 голосов
/ 17 апреля 2020

Мы можем сравнить уровни отдельно. Мы будем использовать трансляцию, чтобы получить все сравнения. Затем мы используем np.select для создания маски умножения.

d = {}
for level in [0, 1]:
    d[level] = (df.index.get_level_values(level).to_numpy()[:, None] 
                 == df.columns.get_level_values(level).to_numpy()[None, :])

conditions = [d[0] & d[1], d[0] & ~d[1], d[1] & ~d[0]]
choice_list = [1, 2, 3]

mult = np.select(conditions, choice_list, default=4)

df.multiply(mult)

       A         B         C
       1    2    1    2    1
A 1  1.0  2.0  3.0  4.0  3.0
  2  2.0  1.0  4.0  3.0  4.0
B 1  3.0  4.0  1.0  2.0  3.0
  2  4.0  3.0  2.0  1.0  4.0
C 1  3.0  4.0  3.0  4.0  1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...