Python 如何合并列为NaN的连续行
我有这样的数据,它让我发疯。源文件是一个pdf文件,我用它来提取表格。问题是表中的某些行在文档中是多行的,这就是我看到输出的方式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
> 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])