Jak sloučit po sobě jdoucí řádky, jejichž sloupce NaN

hlasů
2

Mám tento druh dat, která to zblázním. Zdrojem je pdf soubor, který jsem četl s tabula extrahovat tabulky. Problém je v tom, že některé řádky tabulky jsou víceřádkové v tomto dokumentu, a to je, jak vidím svůj výstup.

> 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

Chtěl bych, aby se něco takového.

> 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

Jsem zápasí s combine_first takto:

sub_df.iloc[[88]].combine_first(sub_df.iloc[[87]])

ale výsledek není to, co jsem očekával.

Také řešení s groupby by ocenili.

Poznámka: index není důležitý a může být vynulován. Jen se chci připojit několik po sobě jdoucí řádky, jejichž sloupce NaN a pak vypsat do CSV, takže jsem je nepotřebují.

Položena 19/12/2018 v 14:14
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
2

Zde je přístup pomocí numpy.wheredělat podmíněné výplň:

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
Odpovězeno 19/12/2018 v 15:18
zdroj uživatelem

hlasů
2

To je docela záludná otázka ani ffill, a bfillbude pracovat na tuto otázku

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
Odpovězeno 19/12/2018 v 15:04
zdroj uživatelem

hlasů
2

Zkusme to:

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()

Výstup:

  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
Odpovězeno 19/12/2018 v 14:29
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more