Python新列基于其他列中的NaN

Python新列基于其他列中的NaN,python,pandas,boolean,nan,nonetype,Python,Pandas,Boolean,Nan,Nonetype,我是Python新手,这是我的第一个问题,所以请对我温柔一点 我已经试过其他类似问题的答案,但还是很困惑 我正在使用Pandas,我有一个数据框,它是来自多个不同SQL表的合并,看起来像这样: Col_1 Col_2 Col_3 Col_4 1 NaN NaN NaN 2 Y NaN NaN 3 Z C S 4 NaN B W 我不关心Col_2 Col_

我是Python新手,这是我的第一个问题,所以请对我温柔一点

我已经试过其他类似问题的答案,但还是很困惑

我正在使用Pandas,我有一个数据框,它是来自多个不同SQL表的合并,看起来像这样:

Col_1   Col_2   Col_3   Col_4
1       NaN     NaN     NaN
2       Y       NaN     NaN
3       Z       C       S
4       NaN     B       W
我不关心Col_2 Col_3和Col_4中的值(注意,根据列的不同,这些值可以是字符串、整数或对象)

我只关心这些列中至少有一列已填充,因此理想情况下,我希望有第五列,如:

Col_1   Col_2   Col_3   Col_4   Col_5
1       NaN     NaN     NaN     0
2       Y       NaN     NaN     1
3       Z       C       S       1
4       NaN     B       W       1
然后我想把列Col_2放到Col_4

我最初的想法类似于下面的函数,但这将我的数据帧从50000行减少到50行。我不想删除任何行

def function(row):
   if (isnull.row['col_2'] and isnull.row['col_3'] and isnull.row['col_3'] is None):
      return '0'
   else:
      return '1'

df['col_5'] = df.apply(lambda row: function (row),axis=1)
任何帮助都将不胜感激。

使用并传递参数
axis=1
,该参数按行进行测试,这将生成一个布尔数组,当转换为int时,将所有
True
值转换为
1
,将
False
值转换为
0
,这将比调用
apply
快得多,后者将逐行迭代,速度非常慢:

In [30]:

df['Col_5'] = any(df[df.columns[1:]].notnull(), axis=1).astype(int)
df
Out[30]:
   Col_1 Col_2 Col_3 Col_4  Col_5
0      1   NaN   NaN   NaN      0
1      2     Y   NaN   NaN      1
2      3     Z     C     S      1
3      4   NaN     B     W      1

In [31]:

df = df[['Col_1', 'Col_5']]
df
Out[31]:
   Col_1  Col_5
0      1      0
1      2      1
2      3      1
3      4      1
以下是
any
的输出:

In [34]:

any(df[df.columns[1:]].notnull(), axis=1)
Out[34]:
array([False,  True,  True,  True], dtype=bool)
计时

In [35]:

%timeit df[df.columns[1:]].apply(lambda x: all(x.isnull()) , axis=1).astype(int)
%timeit any(df[df.columns[1:]].notnull(), axis=1).astype(int)
100 loops, best of 3: 2.46 ms per loop
1000 loops, best of 3: 1.4 ms per loop
因此,根据您对这种尺寸df的测试数据,我的方法比其他答案快2倍以上

更新

当您运行pandas版本
0.12.0
时,需要调用顶级版本,因为该方法在df级别不可用:

any(pd.notnull(df[df.columns[1:]]), axis=1).astype(int)
我建议您升级,因为您将获得更多的功能和错误修复。

使用并传递param
axis=1
,该参数按行进行测试,这将生成一个布尔数组,当转换为int时,将所有
True
值转换为
1
,将
False
值转换为
0
,这将比调用
apply
快得多,后者将逐行迭代,速度非常慢:

In [30]:

df['Col_5'] = any(df[df.columns[1:]].notnull(), axis=1).astype(int)
df
Out[30]:
   Col_1 Col_2 Col_3 Col_4  Col_5
0      1   NaN   NaN   NaN      0
1      2     Y   NaN   NaN      1
2      3     Z     C     S      1
3      4   NaN     B     W      1

In [31]:

df = df[['Col_1', 'Col_5']]
df
Out[31]:
   Col_1  Col_5
0      1      0
1      2      1
2      3      1
3      4      1
以下是
any
的输出:

In [34]:

any(df[df.columns[1:]].notnull(), axis=1)
Out[34]:
array([False,  True,  True,  True], dtype=bool)
计时

In [35]:

%timeit df[df.columns[1:]].apply(lambda x: all(x.isnull()) , axis=1).astype(int)
%timeit any(df[df.columns[1:]].notnull(), axis=1).astype(int)
100 loops, best of 3: 2.46 ms per loop
1000 loops, best of 3: 1.4 ms per loop
因此,根据您对这种尺寸df的测试数据,我的方法比其他答案快2倍以上

更新

当您运行pandas版本
0.12.0
时,需要调用顶级版本,因为该方法在df级别不可用:

any(pd.notnull(df[df.columns[1:]]), axis=1).astype(int)
我建议您升级,因为您将获得更多功能和错误修复。

使用以下功能:

df['col_5'] =df.apply(lambda x: all(x.isnull()) , axis=1)
因为我的钱比较容易读。不确定哪个更快。

使用函数:

df['col_5'] =df.apply(lambda x: all(x.isnull()) , axis=1)

因为我的钱比较容易读。不确定哪一个更快。

我推测您使用的是熊猫数据帧。我已经在您的问题中添加了
pandas
标记。一般来说,如果您使用的第三方库(如pandas)不是Python标准库的一部分,您需要提及。谢谢,我还将更新问题我收集到您使用的是pandas数据框。我已经在您的问题中添加了
pandas
标记。一般来说,您需要提到您是否使用的第三方库(如pandas)不是Python标准库的一部分。谢谢,我还将更新这个问题。我相信OP需要对行、列对执行
操作的行、列对执行
操作。如果列2-4中至少存在一个非NaN值,OP只想使
col5
为真。@aus\u lacy实际上我只需要反转操作,而不是使用
any()尝试使用OR
~
与您的kicks and grins实现一起,无法使其工作,因此我将有兴趣查看您的反转。@因为我已经更新了它,但我需要整理bitAh
notnull()
。我认为OP需要对行、列对执行
操作的行、列对执行
操作。如果列2-4中至少存在一个非NaN值,OP只想使
col5
为真。@aus\u lacy实际上我只需要反转操作,而不是使用
any()尝试使用OR
~
与您的kicks and grins实现一起,无法使其工作,因此我将有兴趣查看您的反转。@因为我已经更新了它,但我需要整理bitAh
notnull()
。错过了那个。