在pandas DataFrame中创建一个新的列,基于其他两个包含NaN值的列。

问题描述 投票:0回答:1

我有一只大熊猫 DataFrame df

                  L C
0         [1, 2, 3] 5
1       [4, nan, 6] 0
2   [nan, nan, nan] 15

和另一个 DataFrame other

    C
0   0
1   25
2   0

然后我附加 otherdf 并在L列中添加3行NaN值。

                  L C   
0         [1, 2, 3] 5   
1       [4, nan, 6] 0   
2   [nan, nan, nan] 15  
0               NaN 0   
1               NaN 25  
2               NaN 0   

我想创建一个列,如果 L 栏目是 NaNC0 那么它就会得到价值 1 否则,它将获得价值 0. 我还对不包含以下内容的行进行计算 NaN 值,但这不在本篇文章的目的之内。

我发现,潘达斯处理 Nan 值是 pd.isna().

我创建了功能

def check_cols(L, C):
  if pd.isna(L) and C == 0:
    return 1
  elif pd.isna(L) and C != 0:
    return 0 

我将函数应用于每一行

df['col'] = df.apply(lambda row: check_cols(row.L,row.C), axis=1)

但我得到的错误

一个有多个元素的数组的真值是模糊的。使用 a.any() 或 a.all()

因为它检查列表中的每个元素,如果是 NaN. 我不想检查列表中的元素,如果有的话。NaN 我想检查是否有一个列表(即使是所有元素nan)或一个 NaN 值。另一种方法是创建一个带有 pd.isna() 这样

                  L C   is_NaN
0         [1, 2, 3] 5   False
1       [4, nan, 6] 0   False
2   [nan, nan, nan] 15  False
0            NaN    0   True
1            NaN    25  True
2            NaN    0   True

然后给函数的三个列作为参数,这样就可以了。我想做同样的检查,如果有一个列表,如果有一个 NaN 值,而不需要在函数中创建额外的列。

如果有人能解释为什么在第一种情况下,它检查列表中的每一个元素,而在第二种情况下,它做我想要的检查,或者提供一些来源,这将是巨大的。

pandas multiple-columns nan
1个回答
0
投票

异常背后的原因是,你应该使用 & 而不是 and 以及 if condition 不能评价为 TrueFalse 因为输出是一个 Series Booleans的。例子:

pd.isna(df.L) & df.C == 0

0     True
1     True
2     True
0     True
1    False
2     True
dtype: bool

上面的结果不能用 if condition.

这里有一个解决方案,直接返回你提到的条件。

import pandas as pd
import numpy as np

def check_cols(L, C):
    return pd.isna(df.L) & (df.C == 0)

data = {
    'L': [[1, 2, 3], [4, np.nan, 6], [np.nan, np.nan, np.nan], np.nan, np.nan, np.nan],
    'C': [5, 0, 15, 0, 25, 0]}

df = pd.DataFrame(data=data, index=[0, 1, 2, 0, 1 ,2])

res = check_cols(df.L, df.C)
df['res'] = res
df

# EDIT: 根据评论更新了解决方案

那么问题是你在应用 pd.isna 到一个列表中--例如第一行中的 L = [1, 2, 3] 第一行中的,且不能由 if condition.

import pandas as pd
import numpy as np

def check_cols(L, C):
    if not isinstance(L, list) and np.isnan(L) and C == 0:
        return 1
    elif not isinstance(L, list) and np.isnan(L) and C != 0:
        return 0 
    else:
        # when L is a list
        return 1

data = {
    'L': [[1, 2, 3], [4, np.nan, 6], [np.nan, np.nan, np.nan], np.nan, np.nan, np.nan],
    'C': [5, 0, 15, 0, 25, 0]
}

df = pd.DataFrame(data=data, index=[0, 1, 2, 0, 1 ,2])

df['col'] = df.apply(lambda row: check_cols(row.L,row.C), axis=1)
df

EDIT 2: 我决定选择 np.nan 但它也适用于 pd.na.

© www.soinside.com 2019 - 2024. All rights reserved.