Кадр даних Pandas fillna () лише деякі колонки на місці


145

Я намагаюся заповнити жодне значення у фреймі даних Pandas 0 не лише для деякого підмножини стовпців.

Коли я роблю:

import pandas as pd
df = pd.DataFrame(data={'a':[1,2,3,None],'b':[4,5,None,6],'c':[None,None,7,8]})
print df
df.fillna(value=0, inplace=True)
print df

Вихід:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  NaN  7.0
3  NaN  6.0  8.0
     a    b    c
0  1.0  4.0  0.0
1  2.0  5.0  0.0
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Він замінює кожен Noneна 0s. Що я хочу зробити, це лише замінити Nones на стовпці aта b, але ні c.

Який найкращий спосіб зробити це?

Відповіді:


219

Ви можете вибрати потрібні стовпці та зробити це за призначенням:

df[['a', 'b']] = df[['a','b']].fillna(value=0)

Отриманий результат, як очікується:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Так, саме цього я хочу! Дякую. Якісь способи зробити це на місці? Мій оригінальний кадр даних досить великий.
Саїт

1
Я не думаю, що жодних результативних результатів немає, роблячи це на місці, так як ви все одно перезаписуєте оригінальний
файл

4
Місце тут зайве, df[['a', 'b']] = df[['a','b']].fillna(value=0)все одно буде працювати
EdChum

2
@EdChum Хіба це не створює тимчасовий фрейм даних і тому для цього потрібно більше пам'яті? (Мене більше хвилює пам’ять, ніж складність часу.)
Саїт

7
Для багатьох операцій, як inplaceі раніше , буде працювати над копією. Я не знаю, чи так це, fillnaчи ні. Дивіться цю відповідь у одного з розробників основних панд.
корінь

85

Ви можете з допомогою dict, fillnaз різним значенням для іншого стовпця

df.fillna({'a':0,'b':0})
Out[829]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

Після присвоїти його назад

df=df.fillna({'a':0,'b':0})
df
Out[831]: 
     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

1
дуже здорово, Btw для диктату, який ви можете використовувати, fromkeysякщо хочете, +1
U10-Вперед

1
Відповідь / приклад був би зрозумілішим, якби він насправді показував різні значення для різних стовпців.
RufusVS

@RufusVS це правильно, але все ж намагайтеся відповідати очікуваному результату
оператора

1
Це найкраще рішення, ніж прийнята відповідь, оскільки це дозволяє уникнути ланцюгових питань індексації, наприклад, якщо вони використовуютьсяdf.fillna({'a':0,'b':0}, inplace=True)
Alex

19

Ви можете уникнути створення копії об'єкта, використовуючи рішення Wen та inplace = Істинно:

df.fillna({'a':0, 'b':0}, inplace=True)
print(df)

Який урожай:

     a    b    c
0  1.0  4.0  NaN
1  2.0  5.0  NaN
2  3.0  0.0  7.0
3  0.0  6.0  8.0

1
Хоча це правильно, уникати копії не обов'язково краще .
jpp

7

Ось як це можна зробити в одному рядку:

df[['a', 'b']].fillna(value=0, inplace=True)

Розбивка: df[['a', 'b']]вибирає стовпці, для яких потрібно заповнити значення NaN, value=0каже йому заповнювати NaN нулями, і inplace=Trueзробить зміни постійними, не потребуючи копії об'єкта.


7

використання верхньої відповіді створює попередження про внесення змін до копії df-фрагмента. Якщо припустити, що у вас є інші стовпці, кращий спосіб зробити це - передати словник:
df.fillna({'A': 'NA', 'B': 'NA'}, inplace=True)


3

Або щось на кшталт:

df.loc[df['a'].isnull(),'a']=0
df.loc[df['b'].isnull(),'b']=0

і якщо є більше:

for i in your_list:
    df.loc[df[i].isnull(),i]=0

0

Іноді цей синтаксис не працює:

df[['col1','col2']] = df[['col1','col2']].fillna()

Замість цього використовуйте наступне:

df['col1','col2']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.