python - 如何减去多索引数据框中的列?

标签 python pandas dataframe subtraction

我有一个像这样的多索引数据框:

import pandas as pd
import numpy as np

df = pd.DataFrame({'ind1': list('aaaaaaaaabbbbbbbbb'),
                   'ind2': list('cccdddeeecccdddeee'),
                   'ind3': list(range(3))*6,
                   'val1': list(range(100, 118)),
                   'val2': list(range(70, 88))})

df_mult = df.set_index(['ind1', 'ind2', 'ind3'])

                val1  val2
ind1 ind2 ind3            
a    c    0      100    70
          1      101    71
          2      102    72
     d    0      103    73
          1      104    74
          2      105    75
     e    0      106    76
          1      107    77
          2      108    78
b    c    0      109    79
          1      110    80
          2      111    81
     d    0      112    82
          1      113    83
          2      114    84
     e    0      115    85
          1      116    86
          2      117    87

我想做的是减去 df_mult.loc['a', 'e', :]df_mult.loc['b', 'e' , :],分别取自df_mult.loc['a', ['c', 'd'], :]df_mult.loc['对应的值b', ['c', 'd'], :], 分别。预期的结果是

                val1  val2
ind1 ind2 ind3            
a    c    0       -6    -6
          1       -6    -6
          2       -6    -6
     d    0       -3    -5
          1       -3    -5
          2       -3    -5
     e    0      106    76
          1      107    77
          2      108    78
b    c    0       -6    -6
          1       -6    -6
          2       -6    -6
     d    0       -3    -3
          1       -3    -3
          2       -3    -3
     e    0      115    85
          1      116    86
          2      117    87

理想情况下,像这样的东西会起作用

df_mult.loc['a', ['c', 'd'], :].subtract(df_mult.loc['a', 'e', :])

但这给了我很多NaN

我该怎么做?

最佳答案

UPDATE2: kind help of @Divakar :

def repeat_blocks(a, repeats=2, block_length=None):
    N = a.shape[0]
    if not block_length:
        block_length = N//2
    out = np.repeat(a.reshape(N//block_length,block_length,-1),
                    repeats,
                    axis=0) \
            .reshape(N*repeats,-1)
    return out

In [234]: df_mult.loc[idx[['a','b'], ['c', 'd'], :], :] -= repeat_blocks(df_mult.loc[['a','b'], 'e', :].values)

In [235]: df_mult
Out[235]:
                val1  val2
ind1 ind2 ind3
a    c    0       -6    -6
          1       -6    -6
          2       -6    -6
     d    0       -3    -3
          1       -3    -3
          2       -3    -3
     e    0      106    76
          1      107    77
          2      108    78
b    c    0       -6    -6
          1       -6    -6
          2       -6    -6
     d    0       -3    -3
          1       -3    -3
          2       -3    -3
     e    0      115    85
          1      116    86
          2      117    87

更新:

In [100]: idx = pd.IndexSlice

In [102]: df_mult.loc[idx['a', ['c', 'd'], :], :] -= \
              np.concatenate([df_mult.loc['a', 'e', :].values] * 2)

In [103]: df_mult
Out[103]:
                val1  val2
ind1 ind2 ind3
a    c    0       -6    -6
          1       -6    -6
          2       -6    -6
     d    0       -3    -3
          1       -3    -3
          2       -3    -3
     e    0      106    76
          1      107    77
          2      108    78
b    c    0      109    79
          1      110    80
          2      111    81
     d    0      112    82
          1      113    83
          2      114    84
     e    0      115    85
          1      116    86
          2      117    87

旧(不正确)答案:

In [62]: df_mult.loc['a', 'e', :] -= df_mult.loc['b', 'e', :].values

In [63]: df_mult
Out[63]:
                val1  val2
ind1 ind2 ind3
a    c    0      100    70
          1      101    71
          2      102    72
     d    0      103    73
          1      104    74
          2      105    75
     e    0       -9    -9
          1       -9    -9
          2       -9    -9
b    c    0      109    79
          1      110    80
          2      111    81
     d    0      112    82
          1      113    83
          2      114    84
     e    0      115    85
          1      116    86
          2      117    87

关于python - 如何减去多索引数据框中的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46593698/

相关文章:

python - Nltk和Python,绘制ROC曲线

python - 使用spyne,尝试在同一元素中生成具有 XML 属性和字符串值的特定 SOAP 响应

python - 仅从数据框中选择某些行的惯用方式(其索引存在于其他数据框中)

PythonSpark : need to execute hive queries from file columns

一组中的 Python Pandas 最大值作为新列

python - 教我 pandas dataframe 的方法来做到这一点?

python - 使用pytest测试同一类的不同实例

python - Pandas Series 参数函数内存

python - 如何提取域名并将其插入新的 Pandas 列?

r - 通过划分两列来创建新的数据列,确定第三列中的除数/除数