如果列名 == 年份且值为 NaN pandas,则将数据框中的值向左移动

Shift values in dataframe to the left if column name == Year and value is NaN pandas

我有一个如下所示的数据框:

                              0    1   2018       3   2017       5
0                    Population    3    NaN  418980    NaN  501433
1                       British    4  31514     NaN  96797     NaN
2                        French  NaN   3089     NaN    201     NaN
3                           NaN  NaN  34603     NaN  96998     NaN

我想得到一个如下所示的数据框:

                              0    1   2018       3   2017       5
0                    Population    3  418980    NaN  501433    NaN
1                       British    4  31514     NaN  96797     NaN
2                        French  NaN   3089     NaN    201     NaN
3                           NaN  NaN  34603     NaN  96998     NaN

其中的逻辑是: 如果年份列具有 NaN 值,请在右侧查找数值并替换 NaN 值。

我想我需要找到任何年份列的索引,查找 df['2018'].isnull(),如果它为空,则在索引中加一,然后搜索相应的值,但我不确定这是否是最好的方法。

pandas 有一个内置函数,用于使用另一列替换原始中的 NA 值:

df[2018] = df[2018].combine_first(df[3])

如果您有很多这样的列,请考虑如何遍历这些列以使用列名称,它是右侧的名称。 (或者我可以帮你)

通过使用@Aryerez 的回答,我想到了这个:

columns_list = list(df.columns) 
year_column_indexes = [i for i, item in enumerate(columns_list) if re.search('201[0-9]', item)]
for _index in year_column_indexes:
    df.iloc[:, _index] = df.iloc[:, _index].combine_first(df.iloc[:, _index+1])
    df = df.drop(df.columns[_index+1], axis=1)

但它需要一些编辑。

想法是用前向填充缺失值替换年到年的下一个值,然后使用 DataFrame.groupby with axis=1 for grouping per columns and get first non missing values if exist by GroupBy.first:

s = df.columns.astype(str).to_series()
a = s.where(s.str.contains('\d{4}')).ffill().fillna(s)
print (a)
0          0
1          1
2018    2018
3       2018
2017    2017
5       2017
dtype: object

df1 = df.groupby(pd.Index(a), axis=1).first()
print (df1)
         0     1         2017      2018
0  Population   3.0  501433.0  418980.0
1     British   4.0   96797.0   31514.0
2      French   NaN     201.0    3089.0
3         NaN   NaN   96998.0   34603.0