Python 如何在数据更改的地方使用位置对数据帧进行索引
我有一个csv文件,它的第一列包含时间,其他列包含其他各种数据。我想删除所有数据在一次到下一次都没有变化的行。我尝试使用drop_duplicates,但这会删除所有重复的行(基于除第一列之外的每一列,因为这样就不会删除任何行),同时我还希望保留数据更改回前一行的实例。例如,如果这是输入:Python 如何在数据更改的地方使用位置对数据帧进行索引,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个csv文件,它的第一列包含时间,其他列包含其他各种数据。我想删除所有数据在一次到下一次都没有变化的行。我尝试使用drop_duplicates,但这会删除所有重复的行(基于除第一列之外的每一列,因为这样就不会删除任何行),同时我还希望保留数据更改回前一行的实例。例如,如果这是输入: time | value A | value B 10:30 | 1 | 2 10:31 | 1 | 2
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
但是,drop DUPS也会在10:35删除最后一行,因为它在“值A”和“值B”列中的值与10:30的第一行相同。我知道很可能没有函数可以单独完成这项工作,所以到目前为止,我提出的唯一解决方案是在每对行上迭代使用drop_duplicates(),但这个过程可能要慢得多。我曾考虑过使用where()或loc()或mask()函数,但似乎找不到更好的解决方案。是我想出的最好的/最快的解决方案还是有更快的解决方案?< /P> < P>从你的问题的描述中,听起来你可以指定一个要考虑的重复的子集的子集,用<代码>子集= ,并指示你希望保留最后的值,使用<代码>保持=最后一次> /代码> ./P>
df.drop_duplicates(keep='last', subset=['valueA', 'valueB'])
演示
>>> 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来保留连续副本的前半部分
>>> dfp = df.set_index('time')
>>> dfp[(dfp.shift(-1) != dfp).any(1)]
valueA valueB
time
10:31 1 2
10:33 2 3
10:34 1 3
10:35 1 2
>>> dfp[(dfp.shift(1) != dfp).any(1)]
valueA valueB
time
10:31 1 2
10:32 2 3
10:34 1 3
10:35 1 2
>dfp=df.set\u索引(“时间”)
>>>dfp[(dfp.移位(-1)!=dfp).任何(1)]
价值A价值B
时间
10:31 1 2
10:33 2 3
10:34 1 3
10:35 1 2
>>>dfp[(dfp.班次(1)!=dfp.任何(1)]
价值A价值B
时间
10:31 1 2
10:32 2 3
10:34 1 3
10:35 1 2
您可以使用shift而不是drop_duplicates来仅删除连续的重复项
df = pd.DataFrame({'val1': [1,1,2,2,1,1], 'val2': [2,2,3,3,3,2]})
df.loc[(df.val1.shift(1) != df.val1) | (df.val2.shift(1) != df.val2)]
val1 val2
0 1 2
2 2 3
4 1 3
5 1 2
一种方法是:
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
ya击败了我,但我根据他的帖子认为应该是
keep='first'
,因为他想删除第一条记录中没有任何更改的行。@MattR“我想保留数据更改回前一列的实例”对我来说听起来像“last”,并且似乎与他想要的输出相匹配。any()的用法与“条件是伟大的”+1不同,我确实打算保留第一行,但正如Mitch在解决方案中所说,我想“保留非连续的重复项”。@JoelKatz那么我想我的第二个解决方案就是您想要的?