根据列前缀将数据帧分为零件,并在零件上执行算术



我有一个表格超过200列的表。这些列带有不同的对(例如,两种类型的奔驰(,是一个示例。我要做的是计算新列的每对差(例如最后一列作为示例(。我当时想根据第一个字母将表与两个表(A& b(分开,然后对列进行排序。但是,熊猫有更有效的方法吗?谢谢!

A_Benz  B_Benz  A_Audi  B_Audi  A_Honda B_Honda dif_Audi
1   0   1   1   0   0   0
1   0   0   1   0   0   -1
1   0   0   1   0   0   -1
1   0   1   1   1   1   0
1   0   0   1   0   0   -1

假设这是您的起点 -

df
   A_Benz  B_Benz  A_Audi  B_Audi  A_Honda  B_Honda
1       1       0       1       1        0        0
2       1       0       0       1        0        0
3       1       0       0       1        0        0
4       1       0       1       1        1        1
5       1       0       0       1        0        0

选项1
这将使filter成为一个不错的用例:

i = df.filter(regex='^A_*')
j = df.filter(regex='^B_*')
i.columns = i.columns.str.split('_', 1).str[-1]
j.columns = j.columns.str.split('_', 1).str[-1]
(i - j).add_prefix('diff_')
   diff_Benz  diff_Audi  diff_Honda
1          1          0           0
2          1         -1           0
3          1         -1           0
4          1          0           0
5          1         -1           0

如果要将其添加回原始数据框,则使用concat

df = pd.concat([df, (i - j).add_prefix('diff_')], axis=1)

选项2
使用diff的替代方案;这有很多不必要的减法:

import re
# if needed, order the columns correctly
df = df[sorted(df.columns, key=lambda x: x.split('_', 1)[1])]
# compute consecutive column differences
df.diff(-1, axis=1).iloc[:, ::2].rename(columns=lambda x: re.sub('A_', 'diff_', x))
   diff_Benz  diff_Audi  diff_Honda
1        1.0        0.0         0.0
2        1.0       -1.0         0.0
3        1.0       -1.0         0.0
4        1.0        0.0         0.0
5        1.0       -1.0         0.0

更性能的版本将是(类似于 @jpp的方法( -

c = sorted(df.columns, key=lambda x: x.split('_', 1)[1])
df = df[c]
pd.DataFrame(
    df.iloc[:, ::2].values - df.iloc[:, 1::2].values, columns=c[::2]
)
   A_Audi  A_Benz  A_Honda
0       0       1        0
1      -1       1        0
2      -1       1        0
3       0       1        0
4      -1       1        0

iiuc

s=pd.Series(df.columns).str.split('_',expand=True)[1]
df.groupby(s.values,axis=1).diff().dropna(axis=1)
Out[1252]: 
   B_Benz  B_Audi  B_Honda
1    -1.0     0.0      0.0
2    -1.0     1.0      0.0
3    -1.0     1.0      0.0
4    -1.0     0.0      0.0
5    -1.0     1.0      0.0

这是基于numpy的解决方案。

虽然性能可能不是问题,但这应该比pandonic方法更有效。

df = df[sorted(df, key=lambda x: x.split('_')[::-1])]
A = df.values
cars = [x[2:] for x in df.columns[::2]]
res = df.join(pd.DataFrame(A[:, ::2] - A[:, 1::2], columns=cars).add_prefix('Diff_'))

结果

   A_Audi  B_Audi  A_Benz  B_Benz  A_Honda  B_Honda  Diff_Audi  Diff_Benz  
0       1       1       1       0        0        0          0          1   
1       0       1       1       0        0        0         -1          1   
2       0       1       1       0        0        0         -1          1   
3       1       1       1       0        1        1          0          1   
4       0       1       1       0        0        0         -1          1   
   Diff_Honda  
0           0  
1           0  
2           0  
3           0  
4           0  

说明

  • 用汽车制作对您的列进行排序。
  • 提取汽车通过列表理解制作。
  • 使用numpy阵列切片来构建差异数据框架并将其加入原始。

最新更新