Свертывание строк с записями NaN в кадре данных панд - PullRequest
0 голосов
/ 20 октября 2018

У меня есть пандас DataFrame со строками данных ::

# objectID        grade  OS     method
object_id_0001    AAA    Mac    organic
object_id_0001    AAA    Mac    NA
object_id_0001    AAA    NA     organic
object_id_0002    NA     NA     NA
object_id_0002    ABC    Win    NA

, т. Е. Часто есть несколько записей для одного и того же objectID, но иногда / часто записи имеют NA.

Как таковой, я просто ищу способ, который бы объединял ObjectID и сообщал о записях, не относящихся к NA, например, приведенное выше сворачивается до ::

object_id_0001    AAA    Mac    organic
object_id_0002    ABC    Win    NA

Ответы [ 3 ]

0 голосов
/ 20 октября 2018

Один альтернативный, более механический способ

def aggregate(s):
    u = s[s.notnull()].unique()
    if not u.size: return np.nan
    return u

df.groupby('objectID').agg(aggregate)

                grade   OS      method
objectID            
object_id_0001  AAA     Mac     organic
object_id_0002  ABC     Win     NaN
0 голосов
/ 20 октября 2018

Это будет работать bfill + drop_duplicates

df.groupby('objectID',as_index=False).bfill().drop_duplicates('objectID')
Out[939]: 
         objectID grade   OS   method
0  object_id_0001   AAA  Mac  organic
3  object_id_0002   ABC  Win      NaN
0 голосов
/ 20 октября 2018

Быстро и Грязно

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

df.groupby('objectID', as_index=False).first()

         objectID grade   OS   method
0  object_id_0001   AAA  Mac  organic
1  object_id_0002   ABC  Win      NaN

pd.concat

pd.concat([
    pd.DataFrame([d.lookup(d.notna().idxmax(), d.columns)], columns=d.columns)
    for _, d in df.groupby('objectID')
], ignore_index=True)

         objectID grade   OS   method
0  object_id_0001   AAA  Mac  organic
1  object_id_0002   ABC  Win      NaN

stack

df.set_index('objectID').stack().groupby(level=[0, 1]).head(1).unstack()

               grade   OS   method
objectID                          
object_id_0001   AAA  Mac  organic
object_id_0002   ABC  Win     None

Если случайно это строки ('NA')

df.mask(df.astype(str).eq('NA')).groupby('objectID', as_index=False).first()
...