Как переместить заполненные ячейки в строках со значениями nan в последнюю строку no-nan в той же ячейке?

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Так что это довольно странный вопрос. По сути, у меня есть df, который выглядит следующим образом:

Игра Платформа
a nintendo
nan PS4
nan Xbox
b PS4
c PS4
nan Xbox

Когда у меня есть nan для игры, это означает, что на самом деле эта платформа должна была быть в последнем столбце платформы для игр, отличных от nan. Итак, вышеуказанное действительно должно быть:

Игра Платформа
a nintendo, ps4, xbox
b PS4
c ps4, xbox

Я попытался собрать быстрое решение:

 cache = set()
last_non_nan = 0

def compress(row):
    global last_non_nan
    global cache
    
    if (type(row['Name']) != type("")) and math.isnan(row['Name']):
        cache.add(row['Platforms'])
        
    elif not cache:
        for item in cache:
            print(atvi_games.at[last_non_nan, 'Platforms'])
            atvi_games.at[last_non_nan, 'Platforms']  = item
            
        last_non_nan = row.name
        cache.clear()
 

Это не работает. Даже если бы это было так, я не могу избавиться от ощущения, что есть какой-то простой способ сделать это, который я не вижу. У кого-нибудь есть идеи? Любая помощь приветствуется.

Ответ №1:

Преобразовать nan в numpy.nan , если это строка:

 import numpy as np
df = df.replace('nan', np.nan, regex=True)
 

Если nan уже np.nan есть, используйте Series.ffill() с Groupby.agg :

 In [2001]: df.game = df.game.ffill()
In [2005]: x = df.groupby('game').agg(','.join).reset_index()

In [2006]: x
Out[2006]: 
  game           platform
0    a  nintendo,ps4,xbox
1    b                ps4
2    c           ps4,xbox
 

Комментарии:

1. Я должен был уточнить изначально, но есть и другие столбцы, похожие на игровой. Это означает, что в строке с платформами стока есть столбцы, которые являются nan, но не nan в предыдущих строках. Ваш метод работает очень хорошо, но я теряю всю остальную информацию.

2. Разобрался со следующим! « x = atvi_games.groupby(‘Name’).agg({‘Year’: ‘first’, ‘Platforms’: lambda x: ‘,’.join(x)}).reset_index() « Спасибо за руководство!

Ответ №2:

Вы можете попробовать groupby :

 # if `nan` is np.nan
# use `df['game'].notna().cumsum()
(df.groupby(df['game'].ne('nan').cumsum(), as_index=False)
   .agg({'game':'first', 'platform':','.join})
)
 

Вывод:

   game           platform
0    a  nintendo,ps4,xbox
1    b                ps4
2    c           ps4,xbox