在Pandas中的列之间替换重复值

Mon*_*eck 9 python pandas

我有一个简单的数据帧:

df = [    {'col1' : 'A', 'col2': 'B', 'col3':   'C', 'col4':'0'},
          {'col1' : 'M', 'col2':   '0', 'col3': 'M', 'col4':'0'},
          {'col1' : 'B', 'col2':  'B', 'col3':  '0', 'col4':'B'},
          {'col1' : 'X', 'col2':  '0', 'col3':  'Y', 'col4':'0'}
          ]
df = pd.DataFrame(df)
df = df[['col1', 'col2', 'col3', 'col4']]
df  
Run Code Online (Sandbox Code Playgroud)

看起来像这样:

| col1 | col2 | col3 | col4 |
|------|------|------|------|
| A    | B    | C    | 0    |
| M    | 0    | M    | 0    |
| B    | B    | 0    | B    |
| X    | 0    | Y    | 0    |
Run Code Online (Sandbox Code Playgroud)

我只是想在行之间用字符'0'替换重复的字符.它归结为保持我们遇到的第一个重复值,如下所示:

| col1 | col2 | col3 | col4 |
|------|------|------|------|
| A    | B    | C    | 0    |
| M    | 0    | 0    | 0    |
| B    | 0    | 0    | 0    |
| X    | 0    | Y    | 0    |
Run Code Online (Sandbox Code Playgroud)

这看起来很简单,但我被卡住了.任何朝着正确方向的推动都会非常感激.

max*_*moo 12

您可以使用该duplicated方法返回元素是否重复的布尔索引器:

In [214]: pd.Series(['M', '0', 'M', '0']).duplicated()
Out[214]:
0    False
1    False
2     True
3     True
dtype: bool
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过将数据映射到数据帧的各行来创建掩码,并使用它where来执行替换:

is_duplicate = df.apply(pd.Series.duplicated, axis=1)
df.where(~is_duplicate, 0)

  col1 col2 col3 col4
0    A    B    C    0
1    M    0    0    0
2    B    0    0    0
3    X    0    Y    0
Run Code Online (Sandbox Code Playgroud)

  • 很好——我正在考虑堆叠/分组/旋转,但这要干净得多。您可以直接使用“pd.Series.duplicated”来避免 lambda,但这只是次要的。 (2认同)