首页 > 解决方案 > 如何使用pandas python对特定列进行操作

问题描述

我有以下数据框:

import pandas as pd
idx = pd.IndexSlice
data = {'Col1': [4, 5, 6, 7, 8], 'Col2': [1, 2, 3, 4, 5], 'Col3': [10, 9, 8, 7, 6],
        'Col4': [5, 8, 9, 3, 10], 'Col5': [7, 6, 4, 5, 8], 'Col6': [4, 5, 6, 7, 8],
        'Col7': [5, 8, 54, 3, 10], 'Col8': [7, 6, 32, 5, 8], 'Col9': [4, 5, 2, 23, 8], 'Col10': [13, 5, 6, 15, 8]}
col = pd.MultiIndex.from_tuples([('Monday', 'Water', 'Cold'), ('Monday', 'Water', 'Hot'),
                                 ('Monday', 'Ice', 'Cold'), ('Monday', 'Ice', 'Hot'), ('Monday', 'Earth', '-'),
                                 ('Tuesday', 'Water', 'Cold'), ('Tuesday', 'Water', 'Hot'),
                                 ('Tuesday', 'Ice', 'Cold'), ('Tuesday', 'Ice', 'Hot'), ('Tuesday', 'Earth', '-')])
df = pd.DataFrame(data)
df.columns = col


  Monday                    Tuesday                   
   Water      Ice     Earth   Water      Ice     Earth
    Cold Hot Cold Hot     -    Cold Hot Cold Hot     -
0      4   1   10   5     7       4   5    7   4    13
1      5   2    9   8     6       5   8    6   5     5
2      6   3    8   9     4       6  54   32   2     6
3      7   4    7   3     5       7   3    5  23    15
4      8   5    6  10     8       8  10    8   8     8

我想做以下操作Ice - Water,应该做以下操作:

('Monday', 'Ice - Water', 'Cold') = ('Monday', 'Ice', 'Cold') - ('Monday', 'Water', 'Cold')
('Monday', 'Ice - Water', 'Hot') = ('Monday', 'Ice', 'Hot') - ('Monday', 'Water', 'Hot')
('Tuesday', 'Ice - Water', 'Cold')  = ('Tuesday', 'Ice', 'Cold') - ('Tuesday', 'Water', 'Cold')
('Tuesday', 'Ice - Water', 'Hot')  = ('Tuesday', 'Ice', 'Hot') - ('Tuesday', 'Water', 'Hot')

df[('Monday', 'Ice - Water', 'Cold')] = df[('Monday', 'Ice', 'Cold')] - df[('Monday', 'Water', 'Cold')]
df[('Monday', 'Ice - Water', 'Hot')] = df[('Monday', 'Ice', 'Hot')] - df[('Monday', 'Water', 'Hot')]
df[('Tuesday', 'Ice - Water', 'Hot')] = df[('Tuesday', 'Ice', 'Hot')] - df[('Tuesday', 'Water', 'Hot')]
df[('Tuesday', 'Ice - Water', 'Cold')] = df[('Tuesday', 'Ice', 'Cold')] - df[('Tuesday', 'Water', 'Cold')]

输出:

      Monday                    Tuesday  ...                Monday         Tuesday     
   Water      Ice     Earth   Water  ... Ice Earth Ice - Water     Ice - Water     
    Cold Hot Cold Hot     -    Cold  ... Hot     -        Cold Hot         Hot Cold
0      4   1   10   5     7       4  ...   4    13           6   4          -1    3
1      5   2    9   8     6       5  ...   5     5           4   6          -3    1
2      6   3    8   9     4       6  ...   2     6           2   6         -52   26
3      7   4    7   3     5       7  ...  23    15           0  -1          20   -2
4      8   5    6  10     8       8  ...   8     8          -2   5          -2    0

我尝试了类似的方法,但失败了:

df_temp = df.loc[:, idx[:, 'Ice', :]] - df.loc[:, idx[:, 'Water', :]]

是否有可能没有许多不必要的for循环?

标签: python-3.xpandas

解决方案


您可以使用rename正确对齐两个 DataFrame:

df_temp = (df.rename(columns={'Ice':'Ice - Water'}).loc[:, idx[:, 'Ice - Water', :]] - 
           df.rename(columns={'Water':'Ice - Water'}).loc[:, idx[:, 'Ice - Water', :]])

print (df_temp)
       Monday         Tuesday    
  Ice - Water     Ice - Water    
         Cold Hot        Cold Hot
0           6   4           3  -1
1           4   6           1  -3
2           2   6          26 -52
3           0  -1          -2  20
4          -2   5           0  -2

然后按第一级排序添加到原始:

df = pd.concat([df, df_temp], axis=1).sort_index(axis=1, level=0, sort_remaining=False)
print (df)
  Monday                                    Tuesday                     \
   Water      Ice     Earth Ice - Water       Water      Ice     Earth   
    Cold Hot Cold Hot     -        Cold Hot    Cold Hot Cold Hot     -   
0      4   1   10   5     7           6   4       4   5    7   4    13   
1      5   2    9   8     6           4   6       5   8    6   5     5   
2      6   3    8   9     4           2   6       6  54   32   2     6   
3      7   4    7   3     5           0  -1       7   3    5  23    15   
4      8   5    6  10     8          -2   5       8  10    8   8     8   

                   
  Ice - Water      
         Cold Hot  
0           3  -1  
1           1  -3  
2          26 -52  
3          -2  20  
4           0  -2  

推荐阅读