Python 如何合并列为NaN的连续行

Python 如何合并列为NaN的连续行,python,pandas,dataframe,Python,Pandas,Dataframe,我有这样的数据,它让我发疯。源文件是一个pdf文件,我用它来提取表格。问题是表中的某些行在文档中是多行的,这就是我看到输出的方式 > sub_df.iloc[85:95] 1 Acronym Meaning 86 ABC Aaaaa Bbbbb Ccccc 87 CDE Ccccc Ddddd Eeeee 88 NaN Fffff Ggggg 89 FGH NaN 90

我有这样的数据,它让我发疯。源文件是一个pdf文件,我用它来提取表格。问题是表中的某些行在文档中是多行的,这就是我看到输出的方式

> sub_df.iloc[85:95]
1      Acronym     Meaning
86      ABC        Aaaaa Bbbbb Ccccc
87      CDE        Ccccc Ddddd Eeeee
88      NaN        Fffff Ggggg 
89      FGH        NaN
90      NaN        Hhhhh
91      IJK        Iiiii Jjjjj Kkkkk
92      LMN        Lllll Mmmmm Nnnnn
93      OPQ        Ooooo Ppppp Qqqqq
94      RST        Rrrrr Sssss Ttttt
95      UVZ        Uuuuu Vvvvv Zzzzz
我想要的是这样的东西

> sub_df.iloc[85:95]
1      Acronym     Meaning
86      ABC        Aaaaa Bbbbb Ccccc
87      CDE        Ccccc Ddddd Eeeee
88      FGH        Fffff Ggggg Hhhhh      
91      IJK        Iiiii Jjjjj Kkkkk
92      LMN        Lllll Mmmmm Nnnnn
93      OPQ        Ooooo Ppppp Qqqqq
94      RST        Rrrrr Sssss Ttttt
95      UVZ        Uuuuu Vvvvv Zzzzz
我正在这样挣扎:

sub_df.iloc[[88]].combine_first(sub_df.iloc[[87]])
但结果并不是我所期望的

此外,如果能提供一个解决方案,我们将不胜感激

注意:索引不重要,可以重置。我只想连接一些列为NaN的连续行,然后将其转储到csv,这样我就不需要它们了。

让我们试试这个:

df = df.assign(Meaning = df['Meaning'].ffill())
mask = ~((df.Meaning.duplicated(keep='last')) & df.Acronym.isnull())

df = df[mask]

df = df.assign(Acronym = df['Acronym'].ffill())

df_out = df.groupby('Acronym').apply(lambda x: ' '.join(x['Meaning'].str.split('\s').sum())).reset_index()
输出:

  Acronym                  0
0     ABC  Aaaaa Bbbbb Ccccc
1     CDE  Ccccc Ddddd Eeeee
2     FGH  Fffff Ggggg Hhhhh
3     IJK  Iiiii Jjjjj Kkkkk
4     LMN  Lllll Mmmmm Nnnnn
5     OPQ  Ooooo Ppppp Qqqqq
6     RST  Rrrrr Sssss Ttttt
7     UVZ  Uuuuu Vvvvv Zzzzz

这是一个相当棘手的问题,
ffill
bfill
都不能解决这个问题

s1=(~(df.Acronym.isnull()|df.Meaning.isnull())) # create the group
s=s1.astype(int).diff().ne(0).cumsum() # create the group for each bad line it will assign the single id 
bad=df[~s1]# we just only change the bad one 
good=df[s1]# keep the good one no change 


bad=bad.groupby(s.loc[bad.index]).agg({'1':'first','Acronym':'first','Meaning':lambda x : ''.join(x[x.notnull()])})


pd.concat([good,bad]).sort_index()
Out[107]: 
    1 Acronym            Meaning
0  86     ABC  Aaaaa Bbbbb Ccccc
1  87     CDE  Ccccc Ddddd Eeeee
2  88     FGH  Fffff Ggggg Hhhhh
5  91     IJK  Iiiii Jjjjj Kkkkk
6  92     LMN  Lllll Mmmmm Nnnnn
7  93     OPQ  Ooooo Ppppp Qqqqq
8  94     RST  Rrrrr Sssss Ttttt
9  95     UVZ  Uuuuu Vvvvv Zzzzz

下面是一种使用
numpy的方法。其中
进行条件填充:

df['Acronym'] = np.where(df[['Acronym']].assign(Meaning=df.Meaning.shift()).isna().all(1),
                         df.Acronym.ffill(),
                         df.Acronym.bfill())

clean_meaning = df.dropna().groupby('Acronym')['Meaning'].apply(lambda x : ' '.join(x)).to_frame()

df_new = (df[['1', 'Acronym']]
          .drop_duplicates(subset=['Acronym'])
          .merge(clean_meaning,
                 left_on='Acronym',
                 right_index=True))

[out]

    1 Acronym            Meaning
0  86     ABC  Aaaaa Bbbbb Ccccc
1  87     CDE  Ccccc Ddddd Eeeee
2  88     FGH  Fffff Ggggg Hhhhh
5  91     IJK  Iiiii Jjjjj Kkkkk
6  92     LMN  Lllll Mmmmm Nnnnn
7  93     OPQ  Ooooo Ppppp Qqqqq
8  94     RST  Rrrrr Sssss Ttttt
9  95     UVZ  Uuuuu Vvvvv Zzzzz

检查
88
的预期输出-应该是
ffffffgggggghhhhhh
没问题,我使用了与您完全相同的方法,然后才意识到输出不是所需的
NaNs
被排除在
groupby
中,因此除非您
fillna
这是熊猫的某种掌握,否则groupby解决方案可能无法工作!我只是编辑了一些东西,因为“1”不是列,而是索引,所以如果复制粘贴,它会给出一个键错误,并且应该是
“”。join
,否则gggghhh将不会被隔开
bad=bad.groupby(good_index.loc[bad.index]).agg({sub_-df.columns[0]:'first',sub_-df.columns[1]:lambda x:''.join(x[x.notnull()]);sub_df=pd.concat([good,bad])。重置索引(drop=True)。排序值(by=sub_df.columns[0])