根据另一列的条件汇总一列的多个连续行中的字符串数据

时间:2019-05-15 16:16:13

标签: python pandas dataframe data-manipulation

我有一个这样的DataFrame:

data = {'col1': ['A', 'B', 'B', 'A', 'B', 'C', 'B', 'B', 'B', 
                  'A', 'C', 'A', 'B', 'C'],
        'col2': ['NaN', 'comment1', 'comment2', 'NaN', 'comment3', NaN,
                 'comment4', 'comment5', 'comment6', 
                 'NaN', 'NaN', 'NaN', 'comment7', 'NaN]}

frame = pd.DataFrame(data)
frame

col1  col2
A     NaN
B     comment1
B     comment2
A     NaN
B     comment3
C     NaN
B     comment4
B     comment5
B     comment6
A     NaN
C     NaN
A     NaN
B     comment7
C     NaN

col1 =='B'的每一行都有一个注释,该注释将是一个字符串。我需要对注释进行聚合,并使用生成的聚合字符串填充上一行(其中col1!='B')。

任何给定的行,其中col1!='B'可能没有任何行,一或多个相应的注释行(col1 =='B'),这似乎是问题的症结所在。我不能只使用fillna('bfill')等。

我研究了iterrows(),groupby()和while循环,并尝试构建自己的函数。但是,我不认为我完全了解所有这些工作原理。

成品应如下所示:

col1    col2
A       comment1 + comment2
B       comment1
B       comment2
A       comment3
B       comment3
C       comment4 + comment5 + comment6
B       comment4
B       comment5
B       comment6
A       NaN
C       NaN
A       comment7
B       comment7
C       NaN

最终,我将删除col1 =='B'的所有行,但现在我想保留它们进行验证。

2 个答案:

答案 0 :(得分:3)

这是将GroupBy与自定义石斑鱼结合使用的一种方式,将col1B的字符串连接起来:

where_a = frame.col1.ne('B') 
g = where_a.cumsum()
com = frame[frame.col1.eq('B')].groupby(g).col2.agg(lambda x: x.str.cat(sep=' + '))
till = (frame.col2.isna() & frame.col2.shift(-1).notna())[::-1].idxmax()
ixs = where_a[:till+1].reindex(frame.index).fillna(False)
frame.loc[ixs, 'col2'] = com.values

print(frame)

    col1                         col2
0     A             comment1 + comment2
1     B                        comment1
2     B                        comment2
3     A                        comment3
4     B                        comment3
5     C  comment4 + comment5 + comment6
6     B                        comment4
7     B                        comment5
8     B                        comment6
9     A                             NaN
10    C                             NaN

答案 1 :(得分:0)

df['col_group'] = -1
col_group = 0
for i in df.index:
    if df.loc[i, 'col1'] != 'B':
        col_group += 1
    df.loc[i, 'col_group'] = col_group

comments = df[df['col1'] == 'B']
transactions = df[df['col1'] != 'B']
agg_comments = comments.groupby('col_group')['col2'].apply(lambda x: reduce(lambda i,j: i+"&$#"+j,x)).reset_index()
df = pd.merge(transactions, agg_comments, on='col_group', how='outer')