groupby并删除pandas中的对记录

时间:2018-04-10 12:32:03

标签: python pandas

我有一个像这样的数据框,

\r

如果col1 col2 col3 col4 a1 b1 c1 + a1 b1 c1 + a1 b2 c2 + a1 b2 c2 - a1 b2 c2 + col1col2中的两个记录具有相同的值且col3中符号相反,则应从数据框中删除它们。

输出:

col4

到目前为止,我尝试过大熊猫col1 col2 col3 col4 a1 b1 c1 + a1 b1 c1 + a1 b2 c2 + duplicated但是没有成功找到对子。怎么做?

4 个答案:

答案 0 :(得分:2)

我认为计数组需要cumcount定义所有4列,然后再次使用帮助Series定义+-组并与set进行比较:< / p>

s = df.groupby(['col1','col2','col3', 'col4']).cumcount()
df = df[~df.groupby(['col1','col2','col3', s])['col4']
           .transform(lambda x: set(x) == set(['+','-']))]
print (df)
  col1 col2 col3 col4
0   a1   b1   c1    +
1   a1   b1   c1    +
6   a1   b2   c2    +

为了更好地理解,请创建新列:

df['help'] = df.groupby(['col1','col2','col3', 'col4']).cumcount()
print (df)
  col1 col2 col3 col4  help
0   a1   b1   c1    +     0
1   a1   b1   c1    +     1
2   a1   b2   c2    +     0
3   a1   b2   c2    -     0
4   a1   b2   c2    +     1

df = df[~df.groupby(['col1','col2','col3', 'help'])['col4']
           .transform(lambda x: set(x) == set(['+','-']))]
print (df)
  col1 col2 col3 col4  help
0   a1   b1   c1    +     0
1   a1   b1   c1    +     1
4   a1   b2   c2    +     1

答案 1 :(得分:1)

这是我的尝试:

df[df.assign(ident=df.assign(count=df.col4.eq('+').astype(int))\
  .groupby(['col1','col2','col3','count']).cumcount())\
  .groupby(['col1','col2','col3','ident']).transform(lambda x: len(x) < 2)['col4']]

输出:

  col1 col2 col3 col4
0   a1   b1   c1    +
1   a1   b1   c1    +
4   a1   b2   c2    +

在更强大的测试集上:

df = pd.DataFrame(
    [['a1', 'b1', 'c1', '+'], ['a1', 'b1', 'c1', '+'], ['a1', 'b2', 'c2', '+'], ['a1', 'b2', 'c2', '-'], ['a1', 'b2', 'c2', '+'],
     ['a1','b3','c3','+'],['a1','b3','c3','-'],['a1','b3','c3','-'],['a1','b3','c3','-'],['a1','b3','c3','+'],['a1','b3','c3','+'],['a1','b3','c3','+'],['a1','b3','c3','+']], 
    columns=['col1', 'col2', 'col3', 'col4']
)

输入数据帧:

   col1 col2 col3 col4
0    a1   b1   c1    +
1    a1   b1   c1    +
2    a1   b2   c2    +
3    a1   b2   c2    -
4    a1   b2   c2    +
5    a1   b3   c3    +
6    a1   b3   c3    -
7    a1   b3   c3    -
8    a1   b3   c3    -
9    a1   b3   c3    +
10   a1   b3   c3    +
11   a1   b3   c3    +
12   a1   b3   c3    +

df[df.assign(ident=df.assign(count=df.col4.eq('+').astype(int))\
  .groupby(['col1','col2','col3','count']).cumcount())\
  .groupby(['col1','col2','col3','ident']).transform(lambda x: len(x) < 2)['col4']]

输出:

   col1 col2 col3 col4
0    a1   b1   c1    +
1    a1   b1   c1    +
4    a1   b2   c2    +
11   a1   b3   c3    +
12   a1   b3   c3    +

答案 2 :(得分:0)

考虑到评论说“如果col1,col2和col3中有两个相同值的记录,col4中符号相反,则应从数据框中删除它们”,然后:

1)识别并删除重复项:df.drop_duplicates()

2)将它们分为三个第一列:df.groupby(['col1', 'col2', 'col3'])

3)只保留大小为1的组(否则,表示我们同时拥有“+”和“ - ”):.filter(lambda group: len(group) == 1)

一体化:

df.drop_duplicates().groupby(['col1', 'col2', 'col3']).filter(lambda g: len(g) == 1)

答案 3 :(得分:0)

首先,按col1col2col3对数据进行分组。然后,应用方法,将在col4中删除具有不同符号的组的行。

在此方法中,将col4+的值替换为1,将-替换为-1。然后将col4中的值相加(让调用变量保持该值signed_row_count)。只有2个结果是可能的,+行将占主导地位(正总和值)或-行将是(负和值)。因此,您可以返回新的数据框,其中signed_row_count行数+符号col4signed_row_count行数-符号col4 {1}},取决于总和的符号。

这是代码:

df = pd.DataFrame(
    [['a1', 'b1', 'c1', '+'], ['a1', 'b1', 'c1', '+'], ['a1', 'b2', 'c2', '+'], ['a1', 'b2', 'c2', '-'], ['a1', 'b2', 'c2', '+']], 
    columns=['col1', 'col2', 'col3', 'col4']
)
print(df)
#   col1 col2 col3 col4
# 0   a1   b1   c1    +
# 1   a1   b1   c1    +
# 2   a1   b2   c2    +
# 3   a1   b2   c2    -
# 4   a1   b2   c2    +

def subtract_rows(df):
    signed_row_count = df['col4'].replace({'+': 1, '-': -1}).sum()

    if signed_row_count >= 0:
       result = pd.DataFrame([df.iloc[0][['col1', 'col2', 'col3']].tolist() + ['+']] * signed_row_count, columns=df.columns)
    else:
        result = pd.DataFrame([df.iloc[0][['col1', 'col2', 'col3']].tolist() + ['-']] * abs(signed_row_count), columns=df.columns)

    return result

reduced_df = (df.groupby(['col1', 'col2', 'col3'])
                .apply(subtract_rows)
                .reset_index(drop=True))
print(reduced_df)
#   col1 col2 col3 col4
# 0   a1   b1   c1    +
# 1   a1   b1   c1    +
# 2   a1   b2   c2    +