python pandas 删除重复的列

新手上路,请多包涵

从数据框中删除重复列的最简单方法是什么?

我正在通过以下方式读取具有重复列的文本文件:

 import pandas as pd

df=pd.read_table(fname)

列名是:

 Time, Time Relative, N2, Time, Time Relative, H2, etc...

所有时间和时间相关列都包含相同的数据。我想:

 Time, Time Relative, N2, H2

我在删除、删除等方面的所有尝试,例如:

 df=df.T.drop_duplicates().T

导致唯一值索引错误:

 Reindexing only valid with uniquely valued index objects

很抱歉成为 Pandas 菜鸟。任何建议,将不胜感激。


额外细节

熊猫版本:0.9.0

蟒蛇版本:2.7.3

Windows 7的

(通过 Pythonxy 2.7.3.0 安装)

数据文件(注意:在真实文件中,列之间用制表符分隔,这里用4个空格分隔):

 Time    Time Relative [s]    N2[%]    Time    Time Relative [s]    H2[ppm]
2/12/2013 9:20:55 AM    6.177    9.99268e+001    2/12/2013 9:20:55 AM    6.177    3.216293e-005
2/12/2013 9:21:06 AM    17.689    9.99296e+001    2/12/2013 9:21:06 AM    17.689    3.841667e-005
2/12/2013 9:21:18 AM    29.186    9.992954e+001    2/12/2013 9:21:18 AM    29.186    3.880365e-005
... etc ...
2/12/2013 2:12:44 PM    17515.269    9.991756+001    2/12/2013 2:12:44 PM    17515.269    2.800279e-005
2/12/2013 2:12:55 PM    17526.769    9.991754e+001    2/12/2013 2:12:55 PM    17526.769    2.880386e-005
2/12/2013 2:13:07 PM    17538.273    9.991797e+001    2/12/2013 2:13:07 PM    17538.273    3.131447e-005

原文由 Onlyjus 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

这是基于重复 列名 删除列的单行解决方案:

 df = df.loc[:,~df.columns.duplicated()].copy()

怎么运行的:

假设数据框的列是 ['alpha','beta','alpha']

df.columns.duplicated() 返回一个布尔数组:a TrueFalse 每列。如果它是 False 那么列名到那时是唯一的,如果它是 True 那么列名之前是重复的。例如,使用给定的示例,返回值将为 [False,False,True]

Pandas 允许使用布尔值进行索引,从而仅选择 True 值。因为我们想保留不重复的列,所以我们需要翻转上面的布尔数组(即 [True, True, False] = ~[False,False,True]

最后, df.loc[:,[True,True,False]] 使用上述索引功能仅选择非重复列。

最后的 .copy() 用于复制数据帧以(主要)避免出现有关稍后尝试修改现有数据帧的错误。

注意:上面只检查列名, 检查列值。

删除重复索引

因为足够相似,所以在索引上做同样的事情:

 df = df.loc[~df.index.duplicated(),:].copy()

通过检查值而不转置来删除重复项

df = df.loc[:,~df.apply(lambda x: x.duplicated(),axis=1).all()].copy()

这样就避免了转置的问题。快吗?不,它有效吗?是的。在这里,试试这个:

 # create a large(ish) dataframe
ldf = pd.DataFrame(np.random.randint(0,100,size= (736334,1312)))

#to see size in gigs
#ldf.memory_usage().sum()/1e9 #it's about 3 gigs

# duplicate a column
ldf.loc[:,'dup'] = ldf.loc[:,101]

# take out duplicated columns by values
ldf = ldf.loc[:,~ldf.apply(lambda x: x.duplicated(),axis=1).all()].copy()

原文由 Gene Burinsky 发布,翻译遵循 CC BY-SA 4.0 许可协议

听起来您已经知道唯一的列名称。如果是这样,那么 df = df['Time', 'Time Relative', 'N2'] 就可以了。

如果没有,您的解决方案应该有效:

 In [101]: vals = np.random.randint(0,20, (4,3))
          vals
Out[101]:
array([[ 3, 13,  0],
       [ 1, 15, 14],
       [14, 19, 14],
       [19,  5,  1]])

In [106]: df = pd.DataFrame(np.hstack([vals, vals]), columns=['Time', 'H1', 'N2', 'Time Relative', 'N2', 'Time'] )
          df
Out[106]:
   Time  H1  N2  Time Relative  N2  Time
0     3  13   0              3  13     0
1     1  15  14              1  15    14
2    14  19  14             14  19    14
3    19   5   1             19   5     1

In [107]: df.T.drop_duplicates().T
Out[107]:
   Time  H1  N2
0     3  13   0
1     1  15  14
2    14  19  14
3    19   5   1

您可能有一些特定于您的数据的东西弄乱了它。如果您可以向我们提供有关数据的更多详细信息,我们可以提供更多帮助。

编辑: 正如安迪所说,问题可能出在重复的列标题上。

对于示例表文件“dummy.csv”,我编写了:

 Time    H1  N2  Time    N2  Time Relative
3   13  13  3   13  0
1   15  15  1   15  14
14  19  19  14  19  14
19  5   5   19  5   1

使用 read_table 给出唯一的列并正常工作:

 In [151]: df2 = pd.read_table('dummy.csv')
          df2
Out[151]:
         Time  H1  N2  Time.1  N2.1  Time Relative
      0     3  13  13       3    13              0
      1     1  15  15       1    15             14
      2    14  19  19      14    19             14
      3    19   5   5      19     5              1
In [152]: df2.T.drop_duplicates().T
Out[152]:
             Time  H1  Time Relative
          0     3  13              0
          1     1  15             14
          2    14  19             14
          3    19   5              1

如果您的版本不允许您使用,您可以拼凑出一个解决方案,使它们独一无二:

 In [169]: df2 = pd.read_table('dummy.csv', header=None)
          df2
Out[169]:
              0   1   2     3   4              5
        0  Time  H1  N2  Time  N2  Time Relative
        1     3  13  13     3  13              0
        2     1  15  15     1  15             14
        3    14  19  19    14  19             14
        4    19   5   5    19   5              1
In [171]: from collections import defaultdict
          col_counts = defaultdict(int)
          col_ix = df2.first_valid_index()
In [172]: cols = []
          for col in df2.ix[col_ix]:
              cnt = col_counts[col]
              col_counts[col] += 1
              suf = '_' + str(cnt) if cnt else ''
              cols.append(col + suf)
          cols
Out[172]:
          ['Time', 'H1', 'N2', 'Time_1', 'N2_1', 'Time Relative']
In [174]: df2.columns = cols
          df2 = df2.drop([col_ix])
In [177]: df2
Out[177]:
          Time  H1  N2 Time_1 N2_1 Time Relative
        1    3  13  13      3   13             0
        2    1  15  15      1   15            14
        3   14  19  19     14   19            14
        4   19   5   5     19    5             1
In [178]: df2.T.drop_duplicates().T
Out[178]:
          Time  H1 Time Relative
        1    3  13             0
        2    1  15            14
        3   14  19            14
        4   19   5             1

原文由 beardc 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题