从下一列中删除 NaN 值和移位值

nma*_*iae 5 python list nan dataframe pandas

我试图从数据框中删除 NaN 值(不删除整个列或行)并将下一个值移动到前一列。例子:

        CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1     1   |   cow    | frog     | NaN     | dog
ROW_2     2   |   pig    | NaN      | cat     | NaN
Run Code Online (Sandbox Code Playgroud)

我的目标是:

       CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1     1   |   cow    | frog     | dog     | NaN
ROW_2     2   |   pig    | cat      | NaN     | NaN
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

  1. 将每一行转换为列表并从每行中删除 NaN。但我似乎无法从列表中删除这些值:

    x = df[df.CLIENT == 1].iloc[:,1:].values.tolist()

然后我得到:

[['cow', 'frog', nan, 'dog']]
Run Code Online (Sandbox Code Playgroud)

删除我尝试过的“nan”:

row_without_nan = [animal for animal in x if str(animal) != 'nan']
Run Code Online (Sandbox Code Playgroud)

但它不会改变列表中的任何内容。我尝试将空值更改为另一个单词并使用该单词,但它也不起作用。

  1. 将每一行转换为数组。我尝试使用 转换为数组np.array(),但它没有用,因为空值变成了'nan',当我尝试使用时,np.isnan我得到了这个:TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

有谁知道我的列表做错了什么,或者是否有更智能/更快的方法来做到这一点?

Sco*_*ton 5

这是一种方法:

df_out = df.apply(lambda x: pd.Series(x.dropna().to_numpy()), axis=1)
df_out = df_out.set_axis(df.columns[:df_out.shape[1]], axis=1).reindex(df.columns, axis=1)
df_out
Run Code Online (Sandbox Code Playgroud)

输出:

       CLIENT ANIMAL_1 ANIMAL_2 ANIMAL_3  ANIMAL_4
ROW_1       1      cow     frog      dog       NaN
ROW_2       2      pig      cat      NaN       NaN
Run Code Online (Sandbox Code Playgroud)

详细信息,在每行上使用 dropna,但随后您需要转换为 numpy 数组以删除索引,然后将列标题分配给原始数据帧并沿列重新索引以拾取数据帧末尾的所有空列。