Python 基于其他列中的 NaN 的新列
Python new column based on NaN in other columns
我是 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)
如有任何帮助,我们将不胜感激。
使用 any
并传递按行测试的参数 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
那么您需要调用顶级 notnull
版本,因为该方法在 df 级别不可用:
any(pd.notnull(df[df.columns[1:]]), axis=1).astype(int)
我建议您升级,因为您将获得更多功能和错误修复。
使用函数:
df['col_5'] =df.apply(lambda x: all(x.isnull()) , axis=1)
因为我的钱更容易阅读。不确定哪个更快。
我是 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)
如有任何帮助,我们将不胜感激。
使用 any
并传递按行测试的参数 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
那么您需要调用顶级 notnull
版本,因为该方法在 df 级别不可用:
any(pd.notnull(df[df.columns[1:]]), axis=1).astype(int)
我建议您升级,因为您将获得更多功能和错误修复。
使用函数:
df['col_5'] =df.apply(lambda x: all(x.isnull()) , axis=1)
因为我的钱更容易阅读。不确定哪个更快。