【pandas】三行代码优雅实现删除连续重复的多行

写代码中遇到的一点小问题,如果快速删除连续重复的多行并且类型是可选择的,重复的数量也是可选择的。
比如:

df=pd.DataFrame.from_dict(
{'id':[1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23],
'value'['equal','equal','insert','equal','equal','equal','equal','delete','delete','delete','equal','delete','insert','insert','insert','insert','equal','equal','equal','equal','equal','equal']})
df
Out[3]: 
    id   value
0    1   equal
1    2   equal
2    3  insert
3    4   equal
4    5   equal
5    6   equal
6    7   equal
7    8  delete
8    9  delete
9   10  delete
10  11   equal
11  13  delete
12  14  insert
13  15  insert
14  16  insert
15  17  insert
16  18   equal
17  19   equal
18  20   equal
19  21   equal
20  22   equal
21  23   equal

删除value=equal,并且连续长度大于等于4的行

最简单的方法就是利用遍历,计算除equal连续长度的累加值,进行判断,然后根据下标进行删除。
但是这样要写很多代码进行逻辑判断。
有没有更简单的方法哪?
基于强大的pandas库,我们是可以优雅的实现以上操作。
首先给出代码:然后一行一行解析

df2 = df.groupby((df['value'].shift() != df['value']).cumsum()).filter(lambda x: len(x) >= 4)
df3 = df2[df2['value'].isin(['equal'])]
result = pd.merge(df, df3, how='left', indicator=True).query("_merge=='left_only'").drop('_merge', 1)

第一行

df.groupby((df['value'].shift() != df['value']).cumsum()).filter(lambda x: len(x) >= 4)

df[‘value’].shift()是将每一行的值下移动一行,
可以看到,第一行变为NaN,值依次往下移动一位。

df['value'].shift()
Out[4]: 
0        NaN
1      equal
2      equal
3     insert
4      equal
5      equal
6      equal
7      equal
8     delete
9     delete
10    delete
11     equal
12    delete
13    insert
14    insert
15    insert
16    insert
17     equal
18     equal
19     equal
20     equal
21     equal
Name: value, dtype: object

shift()可参考这个链接
第二步进行bool运算,不相等为True,相等为False

df['value'].shift() != df['value']
Out[5]: 
0      True
1     False
2      True
3      True
4     False
5     False
6     False
7      True
8     False
9     False
10     True
11     True
12     True
13    False
14    False
15    False
16     True
17    False
18    False
19    False
20    False
21    False
Name: value, dtype: bool

然后cumsum给出一个非降序的id序列,其中每个id表示一个具有相同值的连续块,注意在对布尔值求和时,True被认为是一,而False被认为是零:

(df['value'].shift() != df['value']).cumsum()
Out[6]: 
0     1
1     1
2     2
3     3
4     3
5     3
6     3
7     4
8     4
9     4
10    5
11    6
12    7
13    7
14    7
15    7
16    8
17    8
18    8
19    8
20    8
21    8
Name: value, dtype: int32

对value这一列进行累加计算
cumsum可参考这个链接

最后进行groupby按照相同长度进行聚合

df_group =df.groupby((df['value'].shift() != df['value']).cumsum())
for i in df_group:
   ...:     print(i)
   ...:     
(1,    id  value
0   1  equal
1   2  equal)
(2,    id   value
2   3  insert)
(3,    id  value
3   4  equal
4   5  equal
5   6  equal
6   7  equal)
(4,    id   value
7   8  delete
8   9  delete
9  10  delete)
(5,     id  value
10  11  equal)
(6,     id   value
11  13  delete)
(7,     id   value
12  14  insert
13  15  insert
14  16  insert
15  17  insert)
(8,     id  value
16  18  equal
17  19  equal
18  20  equal
19  21  equal
20  22  equal
21  23  equal)

最后过滤一下长度大于4的连续的值

df.groupby((df['value'].shift() != df['value']).cumsum()).filter(lambda x: len(x) >= 4)
Out[11]: 
    id   value
3    4   equal
4    5   equal
5    6   equal
6    7   equal
12  14  insert
13  15  insert
14  16  insert
15  17  insert
16  18   equal
17  19   equal
18  20   equal
19  21   equal
20  22   equal
21  23   equal

因为我们只需要equal这个值的内容,删除选择特定列可参考这个链接

df2[df2['value'].isin(['equal'])]
Out[16]: 
    id  value
3    4  equal
4    5  equal
5    6  equal
6    7  equal
16  18  equal
17  19  equal
18  20  equal
19  21  equal
20  22  equal
21  23  equal

最后从大的dataframe中删除小的dataframe即可

result = pd.merge(df, df3, how='left', indicator=True).query("_merge=='left_only'").drop('_merge', 1)
Out[17]: 
    id   value
0    1   equal
1    2   equal
2    3  insert
7    8  delete
8    9  delete
9   10  delete
10  11   equal
11  13  delete
12  14  insert
13  15  insert
14  16  insert
15  17  insert

merge操作可参考:这个链接
官方文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/merging.html
其中query的操作是新增一列信息,
可参考:https://blog.csdn.net/AlanGuoo/article/details/88874742

参考:
https://www.code05.com/question/detail/45886518.html

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用Pandas库中的groupby()函数和agg()函数将多行重复数据合并成一行。具体的做法是先读取多行数据到一个PandasDataFrame中,然后使用groupby()函数对重复的数据进行分组,最后使用agg()函数将每组数据合并成一行。示例代码如下: ```python import pandas as pd # 读取多行数据到一个DataFramedf = pd.read_csv('data.csv') # 使用groupby()函数对重复的数据进行分组,然后使用agg()函数将每组数据合并成一行 merged_df = df.groupby(['col1', 'col2'])['col3'].agg(lambda x: ' '.join(x)).reset_index() # 输出合并后的DataFrame print(merged_df) ``` 在上面的示例代码中,我们假设数据已经保存在一个名为`data.csv`的CSV文件中,然后使用Pandas库的read_csv()函数将数据读取到一个DataFrame中。接着使用groupby()函数对DataFrame中的重复数据进行分组,指定分组的列为`col1`和`col2`,并指定需要合并的列为`col3`。最后使用agg()函数对每组数据进行合并,将`col3`列中的多行数据合并成一行,并使用空格分隔。最后使用reset_index()函数将合并后的DataFrame的索引重新编号,然后将结果输出到屏幕上。 需要注意的是,上面的示例代码只是一种合并数据的方式,具体的实现方式需要根据实际情况进行调整。另外,如果需要将多列数据合并成一列,只需要在agg()函数中指定多个列名,然后使用空格或其他分隔符进行连接即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值