Я пытаюсь использовать список в качестве индекса в операции вычитания Dataframe. Однако я получаю следующую ошибку: не может выполнять позиционную индексацию в индексе с этими индексаторами
У меня есть эти два DataFrames:
df1:
показатель | т1 | т2 | т3 | т4 | т5 | ... | т950 |
---|---|---|---|---|---|---|---|
а,1 | 0,00001 | 0,00002 | 0,00003 | 0,00004 | 0,00008 | ... | 0,00004 |
а,2 | 0,00001 | 0,00002 | 0,00003 | 0,00005 | 0,00007 | ... | 0,00004 |
б, 1 | 0,00004 | 0,00003 | 0,00002 | 0,00006 | 0,00006 | ... | 0,00001 |
Би 2 | 0,00005 | 0,00004 | 0,00003 | 0,00007 | 0,00005 | ... | 0,00002 |
дф2:
показатель | т1 | т2 | т3 | т4 | т5 | ... | т950 |
---|---|---|---|---|---|---|---|
а,1 | 0,00008 | 0,00007 | 0,00007 | 0,00006 | 0,00004 | ... | 0,00002 |
а,2 | 0,00007 | 0,00006 | 0,00005 | 0,00004 | 0,00003 | ... | 0,00002 |
б, 1 | 0,00002 | 0,00001 | 0,00002 | 0,00003 | 0,00004 | ... | 0,00004 |
Би 2 | 0,00005 | 0,00006 | 0,00007 | 0,00008 | 0,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,00001 | 0,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 Я просто добавляю больше информации к своему вопросу. В конце я хочу вычесть столбцы, но для каждой строки он должен начинаться в другом столбце на основе значений списка.
Просто мысли вслух. Я думаю, что я бы преобразовал оба из них в numpy, а затем создал версию df2
, где строки были повернуты на указанное вами количество шагов. После этого я мог обойтись df1-df2
без всякой ерунды.
Ах я вижу. Первая строка df1 - df2/offset2. Вторая строка — df1-df2/offset3. Я согласен с ответом @TimRoberts, но векторизованная реализация непроста, см. этот вопрос
Предположим, вы хотите вычесть 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, и он работает как шарм. Я очень ценю вашу помощь!
Можете привести пример операции? Мне непонятно, хотите ли вы вычитать столбцы/строки...