Лучший способ заполнить нулевые значения условиями с использованием Pandas?

#python #pandas #dataframe

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

Вопрос:

Так, например, у меня есть данные, которые выглядят так:

 df = pd.DataFrame([[np.NaN, '1-5'], [np.NaN, '26-100'], ['Yes', 'More than 1000'], ['No', '26-100'], ['Yes', '1-5']], columns=['self_employed', 'no_employees'])
df

    self_employed   no_employees
0   nan                  1-5
1   nan                 26-100
2   Yes            More than 1000
3   No                  26-100
4   Yes                  1-5
 

И я пытаюсь заполнить нулевое значение, исходя из условия, что:

 If no_employees is '1-6' then 'Yes', otherwise 'No'
 

Я смог выполнить это, используя словарь, такой как:

 self_employed_dict = {'1-5': 'Yes', '6-25': 'No', '26-100': 'No', '100-500': 'No', 'More than 1000':'No', '500-1000': 'No'}
df['self_employed'] = df['self_employed'].fillna(df['no_employees'].map(self_employed_dict))
 

Но я хотел знать, есть ли лучший и простой способ сделать это. В этом примере мне пришлось написать словарь для себя, чтобы сопоставить его, так как я могу сделать это разумным способом?

Ожидаемый результат выглядит следующим образом:

     self_employed   no_employees
0   Yes                  1-5
1   No                 26-100
2   Yes            More than 1000
3   No                  26-100
4   Yes                  1-5
 

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

1. ваш self_employed столбец не изменяется. пожалуйста, опубликуйте ожидаемый результат

2. @sammywemmy Ха, это странно.. Я использовал np. NaN для значения nan в примере dataframe…

3. Попробуйте numpy где : df.assign(self_employed=np.where(df.no_employees == "1-5", "Yes", "No"))

Ответ №1:

Использовать fillna — правильный путь, но вместо этого вы могли бы сделать:

 values = df['no_employees'].eq('1-5').map({False: 'No', True: 'Yes'})
df['self_employed'] = df['self_employed'].fillna(values)
print(df)
 

Вывод

   self_employed    no_employees
0           Yes             1-5
1            No          26-100
2           Yes  More than 1000
3            No          26-100
4           Yes             1-5
 

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

1. Отлично работает. против. Однако я чувствую, что это более длительный процесс по сравнению с numpy where (три шага)

Ответ №2:

Ответ зависит от вашей версии pandas. Есть два случая:

  1. Pandas Verion 1.0.0 , для проверки

    print(df['self_employed'].isna()).any() будет возвращать False и/или

    type(df.iloc[0,0]) возвращает тип str .

    В этом случае все элементы вашего фрейма данных имеют тип string и fillna() не будут работать. Это связано с тем, что fillna() функция не будет реагировать на строку nan , поэтому вы можете использовать update() :

 helper = df['no_employees'].eq('1-5').map({False: 'No', True: 'Yes'}).to_frame('self_employed')
df.update(other=helper, filter_func=lambda x: df['self_employed'].eq('nan'))
 
  1. Более старая версия Pandas там типы данных могут быть перепутаны, это означает

    print(df['self_employed'].isna()).any() будет возвращать True и/или

    type(df.iloc[0,0]) возвращает тип float

 values = df['no_employees'].eq('1-5').map({False: 'No', True: 'Yes'})
df['self_employed'] = df['self_employed'].fillna(values)
 

Это поможет вам:

   self_employed    no_employees
0           Yes             1-5
1            No          26-100
2           Yes  More than 1000
3            No          26-100
4           Yes             1-5
 

Ответ №3:

Вы могли бы использовать:

 pd.fillna(0)
 

он заполняет NA / NaN values значением, которое вы хотите (в данном случае 0 ).

Подробнее здесь

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

1. Спрашивающий не пытается заполнить нулем. NaN