Замените значения NaN нескольких столбцов на значения других столбцов в Pandas - PullRequest
0 голосов
/ 17 апреля 2020

С учетом следующего кадра данных:

      date city  gdp  gdp1  gdp2  gross domestic product  pop  pop1  pop2
0  2001-03   bj  3.0   NaN   NaN                     NaN  7.0   NaN   NaN
1  2001-06   bj  5.0   NaN   NaN                     NaN  6.0   6.0   NaN
2  2001-09   bj  8.0   NaN   NaN                     8.0  4.0   4.0   NaN
3  2001-12   bj  7.0   NaN   7.0                     NaN  2.0   NaN   2.0
4  2001-03   sh  4.0   4.0   NaN                     NaN  3.0   NaN   NaN
5  2001-06   sh  5.0   NaN   NaN                     5.0  5.0   5.0   NaN
6  2001-09   sh  9.0   NaN   NaN                     NaN  4.0   4.0   NaN
7  2001-12   sh  3.0   3.0   NaN                     NaN  6.0   NaN   6.0

Я хочу заменить NaN s из gdp и pop значениями gdp1, gdp2, gross domestic product и pop1, pop2 соответственно.

      date city  gdp  pop
0  2001-03   bj    3    7
1  2001-06   bj    5    6
2  2001-09   bj    8    4
3  2001-12   bj    7    2
4  2001-03   sh    4    3
5  2001-06   sh    5    5
6  2001-09   sh    9    4
7  2001-12   sh    3    6

Следующий код работает, но мне интересно, возможно ли сделать его более кратким, поскольку у меня много похожих столбцов?

df.loc[df['gdp'].isnull(), 'gdp'] = df['gdp1']
df.loc[df['gdp'].isnull(), 'gdp'] = df['gdp2']
df.loc[df['gdp'].isnull(), 'gdp'] = df['gross domestic product']
df.loc[df['pop'].isnull(), 'pop'] = df['pop1']
df.loc[df['pop'].isnull(), 'pop'] = df['pop2']
df.drop(['gdp1', 'gdp2', 'gross domestic product', 'pop1', 'pop2'], axis=1)

1 Ответ

2 голосов
/ 17 апреля 2020

Идея состоит в том, чтобы использовать повторное заполнение пропущенных значений, отфильтрованных по DataFrame.filter, если возможно большее количество значений для группы, то установить приоритеты для столбцов с левой стороны, если изменить .bfill(axis=1).iloc[:, 0] на .ffill(axis=1).iloc[:, -1], то установить приоритеты для столбцов из правая сторона:

#if first column is gdp, pop
df['gdp'] = df.filter(like='gdp').bfill(axis=1)['gdp']
df['pop'] = df.filter(like='pop').bfill(axis=1)['pop']

#if possible any first column
df['gdp'] = df.filter(like='gdp').bfill(axis=1).iloc[:, 0]
df['pop'] = df.filter(like='pop').bfill(axis=1).iloc[:, 0]

Но если возможно только одно не пропущенное значение, используйте max, min ...:

df['gdp'] = df.filter(like='gdp').max(axis=1)
df['pop'] = df.filter(like='pop').max(axis=1)

Если необходимо указать имена столбцов по списку:

gdp_c = ['gdp1','gdp2','gross domestic product']
pop_c = ['pop1','pop2']
df['gdp'] = df[gdp_c].bfill(axis=1).iloc[:, 0]
df['pop'] = df[pop_c].bfill(axis=1).iloc[:, 0]

df = df[['date','city','gdp','pop']]
print (df)

      date city  gdp  pop
0  2001-03   bj  3.0  7.0
1  2001-06   bj  5.0  6.0
2  2001-09   bj  8.0  4.0
3  2001-12   bj  7.0  2.0
4  2001-03   sh  4.0  3.0
5  2001-06   sh  5.0  5.0
6  2001-09   sh  9.0  4.0
7  2001-12   sh  3.0  6.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...