python-3.x - 如何使用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
循环?
解决方案
您可以使用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
推荐阅读
- javascript - 如何使用查询风格在 JSON 中插入数据?
- php - Vue,用两条路线共享刀片/视图
- typescript - 如何获取所有可观察数据并将它们合并到 1 个数组中?
- javascript - webgl 读取的像素没有返回正确的值
- javascript - 如何将模块导入在其他地方更改的 AudioWorkletProcessor?
- java - 在 Java 中更改背景颜色的 RadioButton
- c# - 统一卫生系统
- python - 树莓派的 CrossCompilie python 代码
- amazon-web-services - C# AWS SDK SecurityTokenServiceClient.AssumeRole 返回“SignatureDoesNotMatch”403 被禁止
- apache-spark - spark将带有json数组的列爆炸到行