Python 3.x 用Pandas中的其他列值替换多列的“NaN”

Python 3.x 用Pandas中的其他列值替换多列的“NaN”,python-3.x,pandas,dataframe,Python 3.x,Pandas,Dataframe,给出如下数据帧: 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.

给出如下数据帧:

      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
我想用gdp1、gdp2、国内生产总值和pop1、pop2分别替换gdp和pop中的NAN

      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)

想法是使用反填充过滤的缺失值,如果可能,每组中有更多值,则从左侧对列进行优先级排序,如果change.bfillaxis=1.iloc[:,0]到.ffillaxis=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.:

如果需要按列表指定列名称:

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]

想法是使用反填充过滤的缺失值,如果可能,每组中有更多值,则从左侧对列进行优先级排序,如果change.bfillaxis=1.iloc[:,0]到.ffillaxis=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.:

如果需要按列表指定列名称:

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.filterlike='gdp'.bfillaxis=1['gdp']?对不起,过滤器是个好主意,您可以将其保存在aswer中。但在我的数据中,有gdp类型的列与from单词没有相似之处。请检查示例数据的更新。因此,我需要设置需要替换为gdp和pop的列名称,而不是使用筛选方法。@ahbon-我认为此顺序是按列名称列表排列的,例如,gdp_c=['gdp1','gdp2','gdp'],如果选择,则gdp是最后一个。你是对的,无需在第一步设置df的顺序:为什么不使用df.filterlike='gdp'.bfillaxis=1['gdp']?对不起,过滤器是个好主意,您可以将其保存在aswer中。但在我的数据中,有gdp类型的列与from单词没有相似之处。请检查示例数据的更新。因此,我需要设置需要替换为gdp和pop的列名称,而不是使用筛选方法。@ahbon-我认为此顺序是按列名称列表排列的,例如,gdp_c=['gdp1','gdp2','gdp'],如果选择,则gdp是最后一个。你是对的,无需在第一步设置df的顺序: