在SQL語言中去重是一件相當簡單的事情,面對一個表(也可以稱之為DataFrame)我們對數據進行去重只需要GROUP BY 就好。
select custId,applyNo from tmp.online_service_startloan group by custId,applyNo
1.DataFrame去重
但是對於pandas的DataFrame格式就比較麻煩,我看了其他博客優化了如下三種方案。
我們先引入數據集:
import pandas as pd data=pd.read_csv(r'D:/home/nohup.out.20191028.startloan.csv',encoding='utf-8') print(data.info())
共有14936條數據,那我們還是按 custId和applyNo去重。
1.使用list后手寫去重
定義去重函數:我這里使用了遍歷行,添加列表的的方式去重。
# 定義去重函數 def dropRep(df): list2=[] for _,i in df.iterrows(): i=list(i) if i not in list2: list2.append(i) return list2
keydata=data[['custId','applyNo']] len1=keydata.count() print('去重之前custId +applyNo:',len1) list2=dropRep(keydata) print('去重之后custId +applyNo:',len(list2))
2.使用list后set去重
用set去重其實遇到了很多問題,set里面的數據必須是不可變數據類型,可hash等等。。所以只能把key1+key2拼成字符串作為一個元素。
# 定義去重函數 def dropRepBySet(df): set1=set() for _,i in df.iterrows(): set1.add("_".join(list(map(lambda x:str(x),list(i))))) return list(set1)
而且明顯感覺這個方法比上面手寫list遍歷去重快一些
keydata=data[['custId','applyNo']] len1=keydata.count() print('去重之前custId +applyNo:',len1) list2=dropRepBySet(keydata) print('去重之后custId +applyNo:',len(list2))
3.使用pd.DataFrame自帶drop_duplicates()函數去重
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False)
- subset : column label or sequence of labels, optional
用來指定特定的列,默認所有列
- keep : {‘first’, ‘last’, False}, default ‘first’
first刪除重復項並保留第一次出現的項,last刪除重復保留最后一條,False就是刪除重復、只要不重復的數據
- inplace : boolean, default False
是直接在原來數據上修改還是保留一個副本
keydata.drop_duplicates().count()
keydata.drop_duplicates(keep=False).count()
補充提取重復數據
# 剔除重復的數據 data1=keydata.drop_duplicates(keep=False) data1.count()
#至少保留一條 data2=keydata.drop_duplicates(keep="first") data2.count()
#這樣正常的數據就重復了,重復的數據就只有一條 data1.append(data2).drop_duplicates(keep=False).count()
2.Series去重
我也是最近才遇到series去重這個場景,比較了一下兩種去重的性能比較。
場景如下
sql==>pd.dataframe【數據量為8000rows】==>取出這個df的cust_id字段【series】==>轉為list===>下一個sql:'''···where cust_id not in (%s)'''%".".join(list)
方法1:
方法2:seiries.drop_duplicates()