从下一列中删除 NaN 值和移位值
Remove NaN values and shift values from the next column
我正在尝试从数据框中删除 NaN 值(不删除整列或整行)并将下一个值移动到前一列。
示例:
CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1 1 | cow | frog | NaN | dog
ROW_2 2 | pig | NaN | cat | NaN
我的目标是:
CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1 1 | cow | frog | dog | NaN
ROW_2 2 | pig | cat | NaN | NaN
我尝试过的:
将每一行转换为列表并从每一行中删除 NaN。但我似乎无法从列表中删除这些值:
x = df[df.CLIENT == 1].iloc[:,1:].values.tolist()
然后我得到:
[['cow', 'frog', nan, 'dog']]
删除 'nan' 我试过:
row_without_nan = [animal for animal in x if str(animal) != 'nan']
但它不会更改列表中的任何内容。我尝试将空值更改为另一个词并使用该词,但它也没有用。
- 将每一行转换为数组。我尝试使用
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''
有谁知道我的列表有什么问题,或者是否有 smarter/faster 方法来做到这一点?
这是一种方法:
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
输出:
CLIENT ANIMAL_1 ANIMAL_2 ANIMAL_3 ANIMAL_4
ROW_1 1 cow frog dog NaN
ROW_2 2 pig cat NaN NaN
详细信息,在每一行上使用 dropna,但随后您需要转换为 numpy 数组以删除索引,然后将列 headers 分配给原始数据框并沿列重新索引以拾取所有空列数据帧的结尾。
这是另一种方法:
def drop_nan(r):
r = list(r)
r = [x for x in r if isinstance(x, str) or not np.isnan(x)]
return r
res = pd.DataFrame.from_records(df.apply(drop_nan, axis=1))
res.columns = df.columns[:len(res.columns)]
结果是:
CLIENT ANIMAL_1 ANIMAL_2 ANIMAL_3
0 1 cow frog dog
1 2 pig cat None
您的方法可能没问题,但您可能遇到的问题是,在从数据框中获取数组或列表后,您得到了一个嵌套列表,即。 [['cow', 'frog', 南, 'dog']]。注意双括号。你需要摆脱括号对。尝试像 y=x[0] 这样的东西。然后 运行 再次使用您的 nan 删除代码。
我正在尝试从数据框中删除 NaN 值(不删除整列或整行)并将下一个值移动到前一列。 示例:
CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1 1 | cow | frog | NaN | dog
ROW_2 2 | pig | NaN | cat | NaN
我的目标是:
CLIENT| ANIMAL_1 | ANIMAL_2 | ANIMAL_3| ANIMAL_4
ROW_1 1 | cow | frog | dog | NaN
ROW_2 2 | pig | cat | NaN | NaN
我尝试过的:
将每一行转换为列表并从每一行中删除 NaN。但我似乎无法从列表中删除这些值:
x = df[df.CLIENT == 1].iloc[:,1:].values.tolist()
然后我得到:
[['cow', 'frog', nan, 'dog']]
删除 'nan' 我试过:
row_without_nan = [animal for animal in x if str(animal) != 'nan']
但它不会更改列表中的任何内容。我尝试将空值更改为另一个词并使用该词,但它也没有用。
- 将每一行转换为数组。我尝试使用
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''
有谁知道我的列表有什么问题,或者是否有 smarter/faster 方法来做到这一点?
这是一种方法:
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
输出:
CLIENT ANIMAL_1 ANIMAL_2 ANIMAL_3 ANIMAL_4
ROW_1 1 cow frog dog NaN
ROW_2 2 pig cat NaN NaN
详细信息,在每一行上使用 dropna,但随后您需要转换为 numpy 数组以删除索引,然后将列 headers 分配给原始数据框并沿列重新索引以拾取所有空列数据帧的结尾。
这是另一种方法:
def drop_nan(r):
r = list(r)
r = [x for x in r if isinstance(x, str) or not np.isnan(x)]
return r
res = pd.DataFrame.from_records(df.apply(drop_nan, axis=1))
res.columns = df.columns[:len(res.columns)]
结果是:
CLIENT ANIMAL_1 ANIMAL_2 ANIMAL_3
0 1 cow frog dog
1 2 pig cat None
您的方法可能没问题,但您可能遇到的问题是,在从数据框中获取数组或列表后,您得到了一个嵌套列表,即。 [['cow', 'frog', 南, 'dog']]。注意双括号。你需要摆脱括号对。尝试像 y=x[0] 这样的东西。然后 运行 再次使用您的 nan 删除代码。