通过稍微不同的方法,我们可以创建一个 MultiIndex 列并使用对齐来处理计算。然后将joinDataFrame 重新组合起来:
# Columns that don't get split
df = df.set_index('Items')
# Save To Restore Later
og_cols = df.columns
# Create MultiIndex
df.columns = df.columns.str.split('-', expand=True).swaplevel()
# Compute New Cols and put DataFrame back together
df = (
df.set_axis(og_cols, axis=1) # Restore Original Columns
.join(df['sale'] * df['price']) # Add new columns
.reset_index() # Restore Index
)
| Items |
Jan-sale |
Feb-sale |
Mar-sale |
Jan-price |
Feb-price |
Mar-price |
Jan |
Feb |
Mar |
| A |
10 |
25 |
0 |
3 |
3 |
5 |
30 |
75 |
0 |
| B |
15 |
23 |
10 |
2 |
3 |
10 |
30 |
69 |
100 |
| C |
20 |
21 |
5 |
5 |
10 |
15 |
100 |
210 |
75 |
解释:
set_index + str.split 创建一个多索引
df = df.set_index('Items')
df.columns = df.columns.str.split('-', expand=True).swaplevel()
df:
sale price
Jan Feb Mar Jan Feb Mar
Items
A 10 25 0 3 3 5
B 15 23 10 2 3 10
C 20 21 5 5 10 15
这些单独的级别现在可以作为一个组相乘,并且标题是正确的,因为它们在较低的级别上对齐:
df['sale'] * df['price']
Jan Feb Mar
Items
A 30 75 0
B 30 69 100
C 100 210 75
然后我们只是把DataFrame恢复原来的列名set_axis和join放在一起:
# Step 1
df.set_axis(og_cols, axis=1)
Jan-sale Feb-sale Mar-sale Jan-price Feb-price Mar-price
Items
A 10 25 0 3 3 5
B 15 23 10 2 3 10
C 20 21 5 5 10 15
# Step 2
df.set_axis(og_cols, axis=1).join(df['sale'] * df['price'])
Jan-sale Feb-sale Mar-sale Jan-price ... Mar-price Jan Feb Mar
Items ...
A 10 25 0 3 ... 5 30 75 0
B 15 23 10 2 ... 10 30 69 100
C 20 21 5 5 ... 15 100 210 75
[3 rows x 9 columns]
# Step 3
df.set_axis(og_cols, axis=1).join(df['sale'] * df['price']).reset_index()
Items Jan-sale Feb-sale Mar-sale ... Mar-price Jan Feb Mar
0 A 10 25 0 ... 5 30 75 0
1 B 15 23 10 ... 10 30 69 100
2 C 20 21 5 ... 15 100 210 75
[3 rows x 10 columns]
如果我们真的想复制值,我们可以根据需要更新底层的列值:
df.loc[:, 7] = df['Jan-sale'] * df['Jan-price']
df.loc[:, 8] = df['Feb-sale'] * df['Feb-price']
df.loc[:, 9] = df['Mar-sale'] * df['Mar-price']
# Overwrite last 3 values with the first value from columns 1:4 split on '-'
df.columns.values[-3:] = df.columns[1:4].str.split('-').str[0]
但是,这种方法无论如何都需要手动创建初始列,因此迭代几个月的列表可能更直接:
# Iterate to select and create columns
for c in ['Jan', 'Feb', 'Mar']:
df[c] = df[f'{c}-sale'] * df[f'{c}-price']
任一选项都会导致df:
| Items |
Jan-sale |
Feb-sale |
Mar-sale |
Jan-price |
Feb-price |
Mar-price |
Jan |
Feb |
Mar |
| A |
10 |
25 |
0 |
3 |
3 |
5 |
30 |
75 |
0 |
| B |
15 |
23 |
10 |
2 |
3 |
10 |
30 |
69 |
100 |
| C |
20 |
21 |
5 |
5 |
10 |
15 |
100 |
210 |
75 |
设置和导入:
import pandas as pd
df = pd.DataFrame({
'Items': ['A', 'B', 'C'], 'Jan-sale': [10, 15, 20],
'Feb-sale': [25, 23, 21], 'Mar-sale': [0, 10, 5], 'Jan-price': [3, 2, 5],
'Feb-price': [3, 3, 10], 'Mar-price': [5, 10, 15]
})