问题:
有一大一小两个df:df_big 和 df_small,格式如下。其中 df_small 中的记录在 df_big 中也有。现在想把 df_big 中存在的 df_small 记录删掉。
index tdate stk weight id type ind
57304 20181116 603328.SH 0.0069 令狐冲 关注池组合2 电子
57305 20181116 300476.SZ 0.0182 令狐冲 关注池组合2 电子
57306 20181116 603936.SH 0.0029 令狐冲 关注池组合2 电子
57307 20181116 002815.SZ 0.0110 令狐冲 关注池组合2 电子
57308 20181116 603228.SH 0.0144 令狐冲 关注池组合2 电子
57309 20181116 002841.SZ 0.0140 令狐冲 关注池组合2 电子
2、解决方案
1)利用 merge 函数中的 indicator 参数
result = pd.merge(df_big, df_small, how='left', indicator=True).query("_merge=='left_only'").drop('_merge', 1)
merge的语法见[pandas API](http://pandas.pydata.org/pandas-docs/stable/merging.html)
In [47]: result = pd.merge(left, right, how='inner', on=['key1', 'key2'])
2)将内容转成 hash 值后进行比较
a、将两个 df 的行记录,每行内容先合并成一行str,然后将其转成对应的 hash 值,从而得到大小两个 hash 值 Series;
b、对两个 hash 值的 Series进行集合计算,求大 hash 值Series 除去小 hash值Series的结果,得到只存在于大Series中的hash值;
c、确定结果中hash值在大Series中的位置,这个位置就是 df_big 中有,而小df没有的行记录的行索引
# 将series中的一行内容转成一个长串str,之后这行str的hash值并返回
def make_hash(ser):
s1 = (str(ser.T.tolist())[1:-1]).split(',')
s2 = hash(''.join(s1))
return s2
# 将数据转成hash数据
df_big_hash = df_big.apply(make_hash, axis=1)
df_small_hash = df_small.apply(make_hash, axis=1)
# 找出大df中才有的hash行
diff = list(set(df_big_hash).difference(set(df_small_hash)))
# 找到大df中才有的行数据
loca_list = df_big_hash[df_big_hash[0].isin(diff)].index.tolist()
new_record = df_big_hash.loc[loca_list, :]
其中第1个方法比第2个快很多。