熊猫:如何删除熊猫数据框中所有列的前导缺失值?

时间:2020-03-30 16:25:32

标签: python pandas

具有以下形式的pandas数据框:

     A     B     C
ID                
1   10   NaN   NaN
2   20   NaN   NaN
3   28  10.0   NaN
4   32  18.0  10.0
5   34  22.0  16.0
6   34  24.0  20.0
7   34  26.0  21.0
8   34  26.0  22.0

如何删除不同数量的初始缺失值?最初,我想向前填充“新”列的最后一个值,因此我将得出以下结论:

    A     B     C
0  10  10.0  10.0
1  20  18.0  16.0
2  28  22.0  20.0
3  32  24.0  21.0
4  34  26.0  22.0
5  34  26.0  22.0
6  34  26.0  22.0
7  34  26.0  22.0

但是我想在剩余的行上也有nans是自然而然的:

    A     B     C
0  10  10.0  10.0
1  20  18.0  16.0
2  28  22.0  20.0
3  32  24.0  21.0
4  34  26.0  22.0
5  34  26.0   NaN
6  34   NaN   NaN
7  34   NaN   NaN

以下是该问题的直观表示:

之前:

enter image description here

之后:

frea

我想出了一个使用for循环的繁琐方法,其中我使用df.dropna()删除了前导的nan,计算已删除的值的数量(N),将最后一个可用的数字附加N次,并逐列构建新的数据框。但是事实证明,对于较大的数据帧,这相当慢。我觉得这已经是全能熊猫库的内置功能,但是到目前为止我还没有发现任何东西。有没有人建议这样做的麻烦点?

使用示例数据集完成代码:

import pandas as pd
import numpy as np

# sample dataframe
df = pd.DataFrame({'ID':[1,2,3,4,5,6,7,8],
                    'A': [10,20,28,32,34,34,34,34],
                   'B': [np.nan, np.nan, 10,18,22,24,26,26],
                    'C': [np.nan, np.nan, np.nan,10,16,20,21,22]})
df=df.set_index('ID')

# container for dataframe
# to be built using a for loop
df_new=pd.DataFrame()

for col in df.columns:
    # drop missing values column by column
    ser = df[col]
    original_length = len(ser)
    ser_new = ser.dropna()

    # if leading values are removed for N rows.
    # append last value N times for the last rows
    if len(ser_new) <= original_length:
        N = original_length - len(ser_new)
        ser_append = [ser.iloc[-1]]*N
        #ser_append = [np.nan]*N
        ser_new = ser_new.append(pd.Series(ser_append), ignore_index=True)
    df_new[col]=ser_new

df_new

2 个答案:

答案 0 :(得分:2)

我们可以利用shift并将每个序列移动缺失值的数量

d = df.isna().sum(axis=0).to_dict() # calculate the number of missing rows per column 

for k,v in d.items():
    df[k] = df[k].shift(-v).ffill()

-

print(df)

   ID   A     B     C
0   1  10  10.0  10.0
1   2  20  18.0  16.0
2   3  28  22.0  20.0
3   4  32  24.0  21.0
4   5  34  26.0  22.0
5   6  34  26.0  22.0
6   7  34  26.0  22.0
7   8  34  26.0  22.0

答案 1 :(得分:2)

这是一个纯Pandas解决方案。使用apply来根据领先的NaN的数量向上移动值,并使用ffill,

df.apply(lambda x: x.shift(-x.isna().sum())).ffill()


    A      B       C
1   10  10.0    10.0
2   20  18.0    16.0
3   28  22.0    20.0
4   32  24.0    21.0
5   34  26.0    22.0
6   34  26.0    22.0
7   34  26.0    22.0
8   34  26.0    22.0