#python #pandas
#python #pandas
Вопрос:
Я хочу заменить значения nan в «возрастных столбцах» фрейма данных на основе значений, приведенных в сводной таблице,
«0 как женский, 1 как мужской»
Example of df
Pclass Gender Age
3 1 22
1 0 38
2 1 27
3 0 NaN
Pivot table
Age
Gender 0 1
PClass
1 40 35
2 30 28
3 25 21
например, если возраст парня пропущен, и если он / она имеет класс 3 и пол 0, то его возраст равен 25.
У меня около 100 строк, которые необходимо обновить, есть ли быстрый способ?
Комментарии:
1. пожалуйста, предоставьте текст (не изображение) вашего df. Например, вы можете использовать df.to_dict() .
2. в
nan
столбце Age нет s…3. Я только что обновил текст
Ответ №1:
Я бы преобразовал сводную таблицу в обычный df
pdf = pivot_table.stack().reset_index()
затем объедините с nan
df
помощью и combine_first
nan_df = df.loc[df['Age'].isna(), ['Pclass', 'Gender']].merge(pdf, how='left')
df.set_index(['Pclass', 'Gender']).combine_first(nan_df.set_index(['Pclass', 'Gender'])).reset_index()
Pclass Gender Age
0 1 0 38.0
1 2 1 27.0
2 3 0 25.0
3 3 1 22.0
Ответ №2:
Вы можете использовать сначала создать pivot_table
и объединить его обратно df
с дополнительным столбцом из поворота и заменить значения, если NaN
наблюдается
Example of df
Pclass Gender Age
3 1 22
1 0 38
2 1 27
3 0 NaN
Pivot table
Age
Gender 0 1
PClass
1 40 35
2 30 28
3 25 21
import pandas as pd
import numpy as np
df = pd.DataFrame(columns=['PClass','Gender','Age'])
df['PClass'] = [3,1,2,3]
df['Gender'] = [1,0,1,0]
df['Age'] = [22,38,27,np.nan]
df_pivot = pd.pivot_table(df,index=['PClass'],columns=['Gender'],values=['Age'],aggfunc='mean',fill_value=0) ### you can choose your own aggfunc
### I have taken `mean` here , but there ae a bunch of available options
df_pivot = df_pivot.unstack().reset_index().rename(columns={0:'Avg_Age_Pivot'})
df = pd.merge(df,df_pivot[['PClass','Gender','Avg_Age_Pivot']],on=['PClass','Gender'])
def replace_na(inp):
inp = inp.values
if pd.isnull(inp[0]):
return inp[1]
return inp[0]
df['Age'] = df[['Age','Avg_Age']].apply(replace_na,axis=1)
df _pivot O/P --->
>>> pd.pivot_table(df,index=['PClass'],columns=['Gender'],values=['Age'],aggfunc='mean') ### you can choose your own aggfunc
Age
Gender 0 1
PClass
1 38.0 NaN
2 NaN 27.0
3 NaN 22.0
Далее вы можете решить сохранить Avg_Age_Pivot
столбец или удалить его.
Также я заметил, что при объеме предоставленных вами данных в сводной таблице были NaN
значения, поэтому вы не видите желаемого результата с текущими df
значениями
Комментарии:
1. Большое вам спасибо! Однако я не совсем понимаю, что вы подразумеваете под значениями «NaN» в сводной таблице, поскольку в ней ровно 3×2 и 6 записей.
2. Добавлен
df_pivot
вывод в ответе для сводного индекса, где сами данные отсутствовали, функция aggfunc вернетNaN
3. О, я вижу! Это не фактические данные, не беспокойтесь. Спасибо
Ответ №3:
Пожалуйста, ознакомьтесь с этим подходом. Создал общий столбец с именем new, объединив столбцы ‘PClass’ и ‘Gender’. Затем используется map
и df.fillna
для замены значений NaN. Мне пришлось создать этот новый столбец, потому что я могу применить map
метод только на pd.series
.
Входные данные:
import io
df1 = pd.read_csv(io.StringIO("""
PClass Gender Age
3 1 22
1 0 38
2 1 27
3 0 NaN
"""), sep=r"s{1,}", engine="python")
import io
df2 = pd.read_csv(io.StringIO("""
PClass Gender Age
1 0 40
2 0 30
3 0 25
1 1 35
2 1 28
3 1 21
"""), sep=r"s{1,}", engine="python")
df1 (фактический df)
PClass Gender Age
0 3 1 22.0
1 1 0 38.0
2 2 1 27.0
3 3 0 NaN
df2 (Сводная таблица)
PClass Gender Age
0 1 0 40
1 2 0 30
2 3 0 25
3 1 1 35
4 2 1 28
5 3 1 21
Код:
df1['new'] = df1['PClass'].astype(str) df1['Gender'].astype(str)
df2['new'] = df2['PClass'].astype(str) df2['Gender'].astype(str)
fill = df2.set_index(['new'])['Age'].to_dict()
df1['Age'] = df1['Age'].fillna(df1['new'].map(fill))
df1 = df1.drop('new',axis=1)
print(df1)
С принтами:
PClass Gender Age
0 3 1 22.0
1 1 0 38.0
2 2 1 27.0
3 3 0 25.0