【问题标题】:Nested ifs to get values from different column嵌套 ifs 从不同列获取值
【发布时间】:2016-01-14 05:23:45
【问题描述】:

我有一个数据框 df,我想根据应用于其他列的条件填充列中的值

DF的结构,ID后面有几列:

ID ......  col1  col2   col3   col4
1          A1     A1     A1     A1
2          G3            D5
3          R6             
4                 Q3
5          M5     N8

我想创建两个名为“final_col”和“status”的新列,其中“final_col”的值来自 col1 或 col2 或 col3 或 col4,具体取决于哪个 col 具有第一个非空白(非空/NaN)值。

“状态”列只是列的名称

预期输出:

ID ...... col1  col2   col3   col4    final_col     status
1         A1     A1     A1     A1     A1            col1
2                G3            D5     G3            col2
3         R6                   L4     R6            col1
4                                     Not_found     Not_found
5                M5     N8            M5            col2

我知道如何在 excel 中执行此操作,嵌套 if 也是如此,假设 ID 为单元格“A1”

在'final_col'的第一行:

=IF(A2<>"",A2,IF(B2<>"",B2,IF(C2<>"",C2,IF(D2<>"",D2,"Not_found"))))

对于“状态”列

=IF(A2<>"","col1",IF(B2<>"","col2",IF(C2<>"","col3",IF(D2<>"","col4","Not_found"))))

P.S:请在您的解决方案中使用列名,而不是索引,因为数据框的结构可能会有所不同(列的顺序)

提前致谢

【问题讨论】:

  • 您为什么期望在第 4 行获得 Not found?它应该是您数据框中的Q3 吗?

标签: python-3.x pandas dataframe


【解决方案1】:

您可以使用first_valid_index。如果您可以在col1col4 列的某行中的所有NaN 值使用:

print df

   ID col1 col2 col3 col4
0   1   A1   A1   A1   A1
1   2  NaN   G3  NaN   D5
2   3   R6  NaN  NaN  NaN
3   4  NaN  NaN  NaN  NaN
4   5  NaN   M5   N8  NaN

def f1(x):
    if x.first_valid_index() is None:
        return 'Not_found'
    else:
        return str(x.first_valid_index())

def f2(x):
    if x.first_valid_index() is None:
        return 'Not_found'
    else:
        return x[x.first_valid_index()]


df['status'] = df.ix[:, df.columns.tolist().index("col1") :].apply(f1, axis=1)

df['final_col'] = df.ix[:, df.columns.tolist().index("col1") :].apply(f2, axis=1)

print df

   ID col1 col2 col3 col4     status  final_col
0   1   A1   A1   A1   A1       col1         A1
1   2  NaN   G3  NaN   D5       col2         G3
2   3   R6  NaN  NaN  NaN       col1         R6
3   4  NaN  NaN  NaN  NaN  Not_found  Not_found
4   5  NaN   M5   N8  NaN       col2         M5

【讨论】:

  • 如果列“col1”出现在其他十列之后,您能否修改您的答案以使其正常工作,即 first_valid_index 不会指向 col1
【解决方案2】:

你可以使用first_valid_index:

In [105]: df
Out[105]:
   ID col1 col2 col3 col4
0   1   A1   A1   A1   A1
1   2  NaN   G3  NaN   D5
2   3   R6  NaN  NaN  NaN
3   4  NaN  NaN  NaN  NaN
4   5  NaN   M5   N8  NaN

df['status'] = df.iloc[:,1:].apply(lambda x: x.first_valid_index(), axis=1)

df['final_col'] = df.iloc[:, 1:].apply(lambda x: x[x['status']] if x['status'] != None else 'Not found', axis=1)

df['status'].fillna('Not found', inplace=True)

In [129]: df
Out[129]:
   ID col1 col2 col3 col4     status  final_col
0   1   A1   A1   A1   A1       col1         A1
1   2  NaN   G3  NaN   D5       col2         G3
2   3   R6  NaN  NaN  NaN       col1         R6
3   4  NaN  NaN  NaN  NaN  Not found  Not found
4   5  NaN   M5   N8  NaN       col2         M5

【讨论】:

  • 感谢您的解决方案,但如果列 'col1' 出现在其他列 10 列之后,您的解决方案会起作用吗?
  • @user3875610 你有像col + 号码这样的名字吗?我的意思是您可以在该操作之前对您的数据框列进行排序吗?
猜你喜欢
  • 1970-01-01
  • 2018-04-20
  • 2022-11-24
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
相关资源
最近更新 更多