从熊猫数据框中删除重复的列值

时间:2020-07-23 17:52:01

标签: python pandas

我有下面的pandas数据框。在这里,field1,field2 ...始终是变量,Wheras col1,col2 .... coln大多是恒定的,很少更改。最终,我将其保存为实木复合地板格式。实木复合地板内部优化了副本,这不是问题。

我还有另一个要求将其从拼花地板转换为csv.csv文件的大小正在增加。 所以我想删除重复项,然后再将其保存在实木复合地板中。 通过代码执行此操作会增加时间,因为可能会有70-100个这样的列。

date                          field1 field2 col1 col2 col3 col5
20200508062904.8340+0530       11       22      2     3    3   4
20200508062904.8340+0530       12       23      2     3    3   4
20200508062904.8340+0530       13       22      2     3    3   4
20200508062904.8340+0530       14       24      2     3    3   4
20200508051804.8340+0530       14       24      2     3    3   5
20200508051804.8340+0530       14       24      2     4    3   4
20200508051804.8340+0530       14       24      2     3    3   4

对于列(col1 col2 col3 col5),我想保留初始值并删除重复的重复值。 如果这些列在稍后的某个时间点具有与初始值不同的值,则数据帧应保留该值。初始值是相对的,并且等于先前的最新值。

预期产量

 date                          field1 field2 col1 col2 col3 col5
20200508062904.8340+0530       11       22      2   3    3   4
20200508062904.8340+0530       12       23      
20200508062904.8340+0530       13       22      
20200508062904.8340+0530       14       24      
20200508051804.8340+0530       14       24                    5
20200508051804.8340+0530       14       24               4    4
20200508051804.8340+0530       14       24               3        

drop_duplicates帮助删除行,在这种情况下没有用。 有没有更好的方法可以在熊猫中实现这一目标。

3 个答案:

答案 0 :(得分:6)

创建一个掩码,以检查列是否等于其自身已移位,然后填充缺少的值

cols = [x for x in df.columns if x.startswith('col')]

#@AndyL. points out this equivalent mask is far simpler
m = df[cols].ne(df[cols].shift())

df[cols] = df[cols].astype('O').where(m).fillna('')

                       date  field1  field2 col1 col2 col3 col5
0  20200508062904.8340+0530      11      22    2    3    3    4
1  20200508062904.8340+0530      12      23                    
2  20200508062904.8340+0530      13      22                    
3  20200508062904.8340+0530      14      24                    
4  20200508051804.8340+0530      14      24                   5
5  20200508051804.8340+0530      14      24         4         4
6  20200508051804.8340+0530      14      24         3          

以前使用了不必要的复杂蒙版:

m = ~df[cols].ne(df[cols].shift()).cumsum().apply(pd.Series.duplicated)

答案 1 :(得分:3)

您可以使用.where.shift将连续的值设为空白,然后对每一列进行此操作。如果您有很多列,则可以像@ALollz在他的回答中所做的那样循环执行以下操作。

df['col1'] = df['col1'].where(df['col1'] != df['col1'].shift(), '')

带循环的完整代码:

for col in df.columns:
    if 'col' in col:
        df[col] = df[col].where(df[col] != df[col].shift(), '')

输出:

    date                        field1  field2  col1    col2    col3    col5
0   20200508062904.8340+0530    11      22      2       3       3       4
1   20200508062904.8340+0530    12      23              
2   20200508062904.8340+0530    13      22              
3   20200508062904.8340+0530    14      24              
4   20200508051804.8340+0530    14      24                              5
5   20200508051804.8340+0530    14      24              4               4
6   20200508051804.8340+0530    14      24              3       

答案 2 :(得分:1)

您可以尝试将diffwhere与可调用对象一起使用,并将fillnareplaceupdate回到原始df

cols = ['col1', 'col2', 'col3', 'col5']

df.update(df[cols].diff().eq(0).where(lambda x: x)
                               .replace(1,'').fillna(df[cols]))

Out[315]:
                       date  field1  field2 col1 col2 col3 col5
0  20200508062904.8340+0530      11      22    2    3    3    4
1  20200508062904.8340+0530      12      23
2  20200508062904.8340+0530      13      22
3  20200508062904.8340+0530      14      24
4  20200508051804.8340+0530      14      24                   5
5  20200508051804.8340+0530      14      24         4         4
6  20200508051804.8340+0530      14      24         3