Python:在Pandas数据框中合并布尔列

时间:2019-12-19 22:26:21

标签: python pandas

我有以下数据

attr1_A    attr1_B    attr1_C    attr1_D    attr2_A    attr2_B   attr2_C
      1          0          0          1          1          0         0
      0          1          1          0          0          0         1
      0          0          0          0          0          1         0
      1          1          1          0          1          1         0

我想保留attr1_Aattr1_B并将attr1_Cattr1_D合并到attr1_others中。只要attr1_C和/或attr1_D为1,那么attr1_others将为1。同样,我想保留attr2_A,但将其余的attr2_*合并为attr2_others。像这样:

attr1_A    attr1_B    attr1_others    attr2_A    attr2_others
      1          0          1               1               0     
      0          1          1               0               1  
      0          0          0               0               1 
      1          1          1               1               1 

换句话说,对于attr的任何组,我想保留一些已知的列,但要合并其余的列(我不知道同一组中还有多少剩余的attr。< / p>

我正在考虑分别进行每个组的处理:先处理所有attr1_*,然后处理attr2_*,因为我的数据集中的组数量有限,但每个组下的属性很多。

我现在能想到的是检索others列,例如:

# for group 1
df[x for x in df.columns if "A" not in x and "B" not in x and "attr1_" in x]

# for group 2
df[x for x in df.columns if "A" not in x and "attr2_" in x]

要结合使用,我正在考虑使用any函数,但是我无法提出语法。你能帮忙吗?

更新的尝试

我尝试过

# for group 1
df['attr1_others'] = df[df[[x for x in list(df.columns) 
                            if "attr1_" in x
                            and "A" not in x 
                            and "B" not in x]].any(axis = 'column')]

但出现以下错误:

  

ValueError:对象类型<类'pandas.core.frame.DataFrame'>的没有名为列的轴

3 个答案:

答案 0 :(得分:2)

数据框具有强大的就地操作数据的能力,而无需编写复杂的python逻辑。

要创建您的attr1_othersattr2_others列,可以使用以下条件将这些列与or条件合并:

df['attr1_others'] = df['attr1_C'] | df['attr1_D']
df['attr2_others'] = df['attr2_B'] | df['attr2_C']

相反,如果您想要一个and条件,则可以使用:

df['attr1_others'] = df['attr1_C'] & df['attr1_D']
df['attr2_others'] = df['attr2_B'] & df['attr2_C']

然后您可以使用del删除挥之不去的原始值:

del df['attr1_C']
del df['attr1_D']
del df['attr2_B']
del df['attr2_C']

答案 1 :(得分:1)

创建一个保留列列表。删除那些保留的列,并将剩余的列分配给新的数据框df1。按df1分组的列名分组;在轴= 1上呼叫anyadd_suffix'_others'并将结果分配给df2。最后,加入并进行sort_index

keep_cols = ['attr1_A', 'attr1_B', 'attr2_A']
df1 = df.drop(keep_cols,1)
df2 = (df1.groupby(df1.columns.str.split('_').str[0], axis=1)
          .any(1).add_suffix('_others').astype(int))

Out[512]:
   attr1_others  attr2_others
0             1             0
1             1             1
2             0             1
3             1             1

df_final = df[keep_cols].join(df2).sort_index(1)

Out[514]:
   attr1_A  attr1_B  attr1_others  attr2_A  attr2_others
0        1        0             1        1             0
1        0        1             1        0             1
2        0        0             0        0             1
3        1        1             1        1             1

答案 2 :(得分:0)

您可以使用自定义列表选择列,然后使用带有.any()参数的axis=1。要转换为整数,请使用.astype(int)

例如:

import pandas as pd

df = pd.DataFrame({
        'attr1_A': [1, 0, 0, 1],
        'attr1_B': [0, 1, 0, 1],
        'attr1_C': [0, 1, 0, 1],
        'attr1_D': [1, 0, 0, 0],
        'attr2_A': [1, 0, 0, 1],
        'attr2_B': [0, 0, 1, 1],
        'attr2_C': [0, 1, 0, 0]})

cols = [col for col in df.columns.values if col.startswith('attr1') and col.split('_')[1] not in ('A', 'B')]
df['attr1_others'] = df[cols].any(axis=1).astype(int)
df.drop(cols, axis=1, inplace=True)

cols = [col for col in df.columns.values if col.startswith('attr2') and col.split('_')[1] not in ('A', )]
df['attr2_others'] = df[cols].any(axis=1).astype(int)
df.drop(cols, axis=1, inplace=True)

print(df)

打印:

   attr1_A  attr1_B  attr2_A  attr1_others  attr2_others
0        1        0        1             1             0
1        0        1        0             1             1
2        0        0        0             0             1
3        1        1        1             1             1