Вычтите фрейм данных pandas, используя список, чтобы выбрать разные столбцы на каждой итерации

Я пытаюсь использовать список в качестве индекса в операции вычитания Dataframe. Однако я получаю следующую ошибку: не может выполнять позиционную индексацию в индексе с этими индексаторами

У меня есть эти два DataFrames:

df1:

показательт1т2т3т4т5...т950
а,10,000010,000020,000030,000040,00008...0,00004
а,20,000010,000020,000030,000050,00007...0,00004
б, 10,000040,000030,000020,000060,00006...0,00001
Би 20,000050,000040,000030,000070,00005...0,00002

дф2:

показательт1т2т3т4т5...т950
а,10,000080,000070,000070,000060,00004...0,00002
а,20,000070,000060,000050,000040,00003...0,00002
б, 10,000020,000010,000020,000030,00004...0,00004
Би 20,000050,000060,000070,000080,00009...0,00004

И у меня также есть список, который включает индекс для каждого столбца, с которого должно начинаться вычитание:

index_col

[2,3,1,2]

Мой код в настоящее время выглядит следующим образом:

result=df1.subtract(df2.iloc[:,index_col:].rename(columns=dict(zip(df2.iloc[:,index_col:].columns,df2.columns))

Мой ожидаемый результат:

показательт1т2т3т4т5...т950
а,1-0,00006-0,00004-0,00001.........0,00002
а,2-0,00003-0,00001............0,00002
б, 1-0,00003-0,000010,00001-0,00002......0,00004
Би 2-0,00002-0,00004-0,00006.........0,00004

Где, например, в первой строке:

t1 - t3 // t2 - t4 // t3 - t5, потому что в df2 он должен начинаться в третьем столбце (как отражает первое значение index_col).

Знаете ли вы, как я могу рассчитать это вычитание, следуя моему списку в качестве индекса столбца? Я знаю, что могу сделать это с помощью цикла, но я хочу попытаться избежать этого и использовать силу векторизации.

Большое спасибо!

Можете привести пример операции? Мне непонятно, хотите ли вы вычитать столбцы/строки...

Zaero Divide 16.05.2022 23:41

@Zaero Divide Я просто добавляю больше информации к своему вопросу. В конце я хочу вычесть столбцы, но для каждой строки он должен начинаться в другом столбце на основе значений списка.

F. Nielsen 16.05.2022 23:56

Просто мысли вслух. Я думаю, что я бы преобразовал оба из них в numpy, а затем создал версию df2, где строки были повернуты на указанное вами количество шагов. После этого я мог обойтись df1-df2 без всякой ерунды.

Tim Roberts 17.05.2022 00:02

Ах я вижу. Первая строка df1 - df2/offset2. Вторая строка — df1-df2/offset3. Я согласен с ответом @TimRoberts, но векторизованная реализация непроста, см. этот вопрос

Zaero Divide 17.05.2022 00:06
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
40
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предположим, вы хотите вычесть 0, когда строка закончится.

Пусть shifts будет списком [2,3,1,2], который вы называете index_col.

Возможно, это не самое красивое/элегантное решение, но я думаю, что это сделает то, что вы хотите:

import numpy as np
from scipy.ndimage import shift

shifted = np.vstack([shift(row, -k) for row, k in zip(df2.values, shifts)])
result = df1 - shifted

Полный пример:

import numpy as np
import pandas as pd
from scipy.ndimage import shift


df1 = pd.DataFrame(np.random.random((4, 5)), index=list("ABCD"), columns=list("abcde"))
df2 = pd.DataFrame(np.random.random((4, 5)))
shifts = [2, 3, 1, 2]
>>> df1
          a         b         c         d         e
A  0.308420  0.591043  0.914204  0.407474  0.670670
B  0.371686  0.989710  0.823255  0.145337  0.437014
C  0.023323  0.590014  0.685122  0.558222  0.238016
D  0.996939  0.974608  0.117192  0.539702  0.622569

>>> df2
          0         1         2         3         4
0  0.825861  0.356216  0.668553  0.090403  0.915279
1  0.699088  0.239835  0.728388  0.143411  0.025266
2  0.600219  0.280567  0.267376  0.100538  0.511053
3  0.538059  0.705963  0.633112  0.138550  0.455539

>>> shifted = np.vstack([shift(row, -k) for row, k in zip(df2.values, shifts)])
>>> df1 - shifted
          a         b         c         d         e
A -0.360133  0.500640 -0.001074  0.407474  0.670670
B  0.228275  0.964444  0.823255  0.145337  0.437014
C -0.257244  0.322639  0.584583  0.047168  0.238016
D  0.363827  0.836059 -0.338347  0.539702  0.622569

Если вы не хотите импортировать scipy, вы можете написать свою собственную функцию shift: см. Сдвиг элементов в массиве numpy.

Наконец, я использовал scipy, и он работает как шарм. Я очень ценю вашу помощь!

F. Nielsen 17.05.2022 10:15

Другие вопросы по теме