在数据框中合并两个同名列

3

我有一个类似这样的数据框:

df = pd.DataFrame({'a':[1,0,1],'b':[0,1,0],'b1':[1,0,0],'c':[0,1,1]})
df.columns = ['a','b','b','c']

>>> df
   a  b  b  c
0  1  0  1  0
1  0  1  0  1
2  1  0  0  1

我想把这两个不同的b列合并在一起,像这样:
   a  b  c
0  1  1  0
1  0  1  1
2  1  0  1

我知道在位运算的上下文中可以使用 |(或)将它们组合起来,例如与 ac 一起使用:

>>> df['a'] | df['c']
0    1
1    1
2    1
dtype: int64

但我在选择两个单独的 b 列时遇到了问题,原因是这样的:

>>> df['b']
   b  b
0  0  1
1  1  0
2  0  0

>>> df['b']['b']
   b  b
0  0  1
1  1  0
2  0  0

>>> df['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']['b']
   b  b
0  0  1
1  1  0
2  0  0

1
你应该为“join”(实际上它并不是一个join)指定一些规则。在这种情况下,我从数据中解释出你的列只包含0或1,并且1会覆盖0。就这样吗? - Ric S
是的@Ric。我希望'b'最终变成'1,1,0',因为这两个'b'分别是'0,1,0'和'1,0,0'。 - user17242583
1
df["b"].sum(axis=1).clip(0, 1)? Or df["b"].apply(lambda x: x[0]|x[1], axis=1) - not_speshal
很好,@Chris - 这也很有用。我确实想要删除多余的一个。 - user17242583
你为什么要在第一列中使用重复的列名呢? - Quang Hoang
显示剩余2条评论
3个回答

2
尝试使用sumclip函数:
df["b"] = df["b"].sum(axis=1).clip(0, 1)

#remove duplicate column
df = df.loc[:, ~df.columns.duplicated()]

调用 clip 甚至似乎并不必要。 - user17242583
1
如果两个“b”列都有“1”,则您将获得“2”而不是“1”。 - not_speshal
@user17242583 如需保留其他列,请使用“df.groupby(level=0, axis=1).sum().clip(0, 1)”(按它们的标签对列进行分组并将逻辑应用于每个组) - Rodalm
1
@HarryPlotter - 如果有多个重复列,那么这样做是有意义的。否则,我的方法更快(每次循环28.5 ns ± 1.04 ns vs每次循环2.55 ms ± 112 µs)。我的代码也会在更大的数据框中变得更加高效(1000倍以上的数据框:每次循环30.3 ns ± 0.809 ns vs每次循环3.41 ms ± 206 µs)。 - not_speshal
1
是的,自然会慢一些。但是在 OP 想要将逻辑推广到不同列组的情况下,这种方法就非常有用了。 - Rodalm
1
我想我会使用你的@HarryPlotter,因为虽然我喜欢not_speshal提供的这个快速解决方案,但是重复的列将是任意的,所以你的解决方案对我的特定情况更有效。你能把它放在答案里吗? - user17242583

1

除了not_speshal提供的答案,你还可以按照以下方式通过索引访问列:

df.iloc[:, 1] | df.iloc[:, 2]

1
假设您有多个重复列的组,您可以使用 DataFrame.groupby 将每个组应用与 not_speshal 的解决方案 相同的逻辑。请注意保留 HTML 标签。
# group the columns (axis=1) by their labels (level=0) and apply the logic to each group
df = df.groupby(level=0, axis=1).sum().clip(0, 1) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接