如何在 pandas 中删除具有不同列名称的重复数据?

7

我有一个DataFrame,其中有重复数据但名称不同的列:

In[1]: df
Out[1]: 
  X1   X2  Y1   Y2
 0.0  0.0  6.0  6.0
 3.0  3.0  7.1  7.1
 7.6  7.6  1.2  1.2

我知道.drop(columns = )可以删除列,但是否有更有效的方法可以不用列出所有要删除的列名呢?请告诉我,因为我可以使用 .drop()。

2个回答

7

我们可以在轴1上使用 np.unique。不幸的是,pandas没有内置函数来删除重复的列。

df.drop_duplicates 只会移除重复的行。

返回删除了重复行的DataFrame。

我们可以围绕 np.unique 创建一个函数来删除重复的列。

def drop_duplicate_cols(df):
    uniq, idxs = np.unique(df, return_index=True, axis=1)
    return pd.DataFrame(uniq, index=df.index, columns=df.columns[idxs])

drop_duplicate_cols(X)
    X1   Y1
0  0.0  6.0
1  3.0  7.1
2  7.6  1.2

在线演示

NB: np.unique 文档:

返回数组的排序唯一元素。

解决方法: 为了保留原始顺序,请对 idxs 进行排序。


在拥有多个dtypes的数据框上使用.T将会干扰你的实际dtypes

df = pd.DataFrame({'A': [0, 1], 'B': ['a', 'b'], 'C': [0, 1], 'D':[2.1, 3.1]})
df.dtypes
A      int64
B     object
C      int64
D    float64
dtype: object

df.T.T.dtypes
A    object
B    object
C    object
D    object
dtype: object
# To get back original `dtypes` we can use `.astype`
df.T.T.astype(df.dtypes).dtypes
A      int64
B     object
C      int64
D    float64
dtype: object

2
这应该会更快,因为它使用numpy函数在numpy数组上操作而无需转换形状。+1 - anky
2
@anky 謝謝:D 我相信 .T 有一定的開銷。對於 OP 的數據, timeit 測試表明 np.unique 快了近8倍。但是我猜 np.unique 不會很好地擴展,我在某個地方讀到過這個說法。 - Ch3steR
2
@anky 另一个重要缺陷是当一个 df 有多个类型时,.T 也会改变 dtype。 - Ch3steR
不是缺陷,而是需要知道的注意事项。 - Ch3steR
1
@ahnnni 在线演示 正常工作。 - Ch3steR
显示剩余2条评论

6
你可以使用 Tdrop_duplicates 进行转置,然后再转回来:
>>> df.T.drop_duplicates().T
    X1   Y1
0  0.0  6.0
1  3.0  7.1
2  7.6  1.2
>>> 

或使用locduplicated:

>>> df.loc[:, df.T.duplicated(keep='last')]
    X1   Y1
0  0.0  6.0
1  3.0  7.1
2  7.6  1.2
>>> 

抱歉,我忘了提到这一点,但是我的数据还有另一列没有重复,例如X1 X2 Y1 Y2 Z。我注意到使用这个代码会完全删除Z列。如何编写代码以使这一列成为例外? - ahnnni
@ahnnni 使用第一种解决方案。 - U13-Forward
@ahnnni 第一个解决方案应该可以。 - U13-Forward

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