从大 df 中删除小 df 具有的记录

问题:
有一大一小两个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个快很多。

上一篇:Java> Java核心卷读书笔记 - 枚举类


下一篇:gym 100958 b 题解