如何在数据发生变化的地方使用位置索引pandas数据帧

时间:2017-03-03 20:30:18

标签: python pandas dataframe

我有一个csv文件,其第一列由时间组成,其他列包含其他各种数据。我想删除所有没有数据从一次更改到下一次的行。我尝试使用drop_duplicates,但是这会删除所有重复的行(基于除第一列之外的每一列,因为这样就不会删除任何行)而我还希望保留数据更改回前一行的实例。例如,如果这是输入:

time    |    value A   |   value B
10:30   |       1      |     2    
10:31   |       1      |     2    
10:32   |       2      |     3    
10:33   |       2      |     3    
10:34   |       1      |     3    
10:35   |       1      |     2    

我想要这个输出:

time    |    value A   |   value B
10:30   |       1      |     2      
10:32   |       2      |     3    
10:34   |       1      |     3    
10:35   |       1      |     2   

然而,丢弃对话也会删除10:35的最后一行,因为它在列中具有相同的值'值A'和'价值B'作为10:30的第一行。我知道很可能没有能够单独执行此操作的函数,因此到目前为止我唯一提出的解决方案是在每对行上迭代使用drop_duplicates(),但此过程可能要慢得多。我在考虑使用where()或loc()或mask()函数,但似乎无法提出任何更好的解决方案。我提出的解决方案是最好的/最快的还是有更快的解决方案?

3 个答案:

答案 0 :(得分:3)

从您的问题描述中,您可以只指定要使用subset=的重复项的列子集,并指出您希望将 last 值保留为{ {1}}。

keep='last'

<强>演示

df.drop_duplicates(keep='last', subset=['valueA', 'valueB'])

如果要保留非连续重复项(与样本输出不匹配),可以使用shift()和-1作为保留后半部分连续重复,或1保留连续重复的前半部分。

>>> df

    time  valueA  valueB
0  10:31       1       2
1  10:32       2       3
2  10:33       2       3
3  10:34       1       3
4  10:35       1       2

>>> df.drop_duplicates(keep='last', subset=['valueA', 'valueB'])

    time  valueA  valueB
2  10:33       2       3
3  10:34       1       3
4  10:35       1       2

答案 1 :(得分:1)

您可以使用shift而不是drop_duplicates来仅删除连续的重复项

$('#send_profile').click(function(event) {
    event.preventDefault();

    $.ajax({
        global: false,
        type: 'POST',
        url: /user/change,
        dataType: 'html',
        data: {
            name: $("#profile_name").val(),
            surname: $("#profile_surname").val(),
            age: $("#profile_age").val()
        },
        success: function (result) {
            console.log(result);
        },
        error: function (request, status, error) {
            serviceError();
        }
    });
});

答案 2 :(得分:0)

一种方法:

In [9]: df
Out[9]: 
    time  valueA  valueB
0  10:30       1       2
1  10:31       1       2
2  10:32       2       3
3  10:33       2       3
4  10:34       1       3
5  10:35       1       2

In [10]: compose=df.filter(like='val')

In [11]: good = (compose != compose.shift()).any(1)

In [12]: df[good]
Out[12]: 
    time  valueA  valueB
0  10:30       1       2
2  10:32       2       3
4  10:34       1       3
5  10:35       1       2