Python 筛选列表中与每行的条件匹配的第一个元素

Python 筛选列表中与每行的条件匹配的第一个元素,python,pandas,list,filtering,Python,Pandas,List,Filtering,问题/问题:我想创建另一列,该列包含列表中多个/或值的第一列,该列表符合不同于nan的条件 我正在研究一个数据帧,它有多个列作为标志,每一列都是一种不同的标志。这就是它看起来的样子: id_number createdat ... flag_3.3.3.2.1 flag_3.3.3.2.2 flag_3.3.3.3.1 1 718v 2019-08-14 ... nan 3.3.3.2.2 3.3.3.3.

问题/问题:我想创建另一列,该列包含列表中多个/或值的第一列,该列表符合不同于nan的条件

我正在研究一个数据帧,它有多个列作为标志,每一列都是一种不同的标志。这就是它看起来的样子:

         id_number  createdat  ... flag_3.3.3.2.1 flag_3.3.3.2.2 flag_3.3.3.3.1
1             718v 2019-08-14  ...            nan      3.3.3.2.2      3.3.3.3.1
2             566m 2019-07-10  ...            nan            nan            nan
3             636p 2019-06-12  ...      3.3.3.2.1            nan      3.3.3.3.1
4             630r 2019-06-30  ...            nan            nan            nan
26815         066p 2019-08-24  ...      3.3.3.2.1      3.3.3.2.2      3.3.3.3.1
26816         769b 2019-08-10  ...            nan            nan            nan
我已成功创建了一个列,该列生成包含以下内容的列的所有值的列表:

payday_cols = [col for col in df if col.startswith('flag_')]
df['flagging'] = df[payday_cols].values.tolist()
print(df)
         id_number  ... flag_3.3.3.3.1                                           flagging
1             718v  ...            nan  [nan, nan, nan, nan, nan, nan, nan, nan, nan, ...
2             566m  ...            nan  [nan, nan, nan, nan, nan, nan, nan, nan, nan, ...
3             636p  ...            nan  [nan, nan, 2.2, nan, nan, nan, nan, nan, nan, ...
4             630r  ...            nan  [nan, nan, nan, 3.1, nan, nan, nan, nan, 3.3.2...                                          ...
26815         066p  ...      3.3.3.3.1  [nan, nan, nan, nan, 3.2, nan, nan, nan, nan, ...
26816         769b  ...            nan  [1, nan, nan, nan, nan, nan, nan, nan, 3.3.2.1...
我缺少的是创建最后一列的方法,该列包含列表中与nan不同的第一个值,如果没有与nan不同的值,则为nan。输出结果如下:

         id_number  ... flag_3.3.3.3.1                                           flagging      flag
1             718v  ...            nan  [nan, nan, nan, nan, nan, nan, nan, nan, nan, ...       nan
2             566m  ...            nan  [nan, nan, nan, nan, nan, nan, nan, nan, nan, ...       nan
3             636p  ...            nan  [nan, nan, 2.2, nan, nan, nan, nan, nan, nan, ...       2.2
4             630r  ...            nan  [nan, nan, nan, 3.1, nan, nan, nan, nan, 3.3.2...       3.1
26815         066p  ...      3.3.3.3.1  [nan, nan, nan, nan, 3.2, nan, nan, nan, nan, ...       3.2
26816         769b  ...            nan  [1, nan, nan, nan, nan, nan, nan, nan, 3.3.2.1...   3.3.2.1
非常感谢,如果您需要我生成类似于这些值的值,以便您可以重新创建此案例,我将用它编辑此文章。

这应该可以

df = pd.DataFrame({
    "flagging": [[np.nan, np.nan, np.nan, np.nan], [np.nan, 2.2, np.nan, 0.2], [np.nan, 1.1, np.nan, np.nan], [np.nan, np.nan, np.nan, 3.1]]
})

def get_element(xs):
    xs = [x for x in xs if not pd.isna(x)]
    if xs:
        return xs[0]
    return np.nan

df["flagging"].apply(get_element)
输出:

0    NaN
1    2.2
2    1.1
3    3.1
这应该行得通

df = pd.DataFrame({
    "flagging": [[np.nan, np.nan, np.nan, np.nan], [np.nan, 2.2, np.nan, 0.2], [np.nan, 1.1, np.nan, np.nan], [np.nan, np.nan, np.nan, 3.1]]
})

def get_element(xs):
    xs = [x for x in xs if not pd.isna(x)]
    if xs:
        return xs[0]
    return np.nan

df["flagging"].apply(get_element)
输出:

0    NaN
1    2.2
2    1.1
3    3.1
方法1:

试试bfill和.iloc

方法2:

另一个解决方案是在notna上使用numpy argmax并将结果传递给lookup

注:输出基于此示例

In [83]: df

Out[83]:
      id_number   createdat flag_3.3.3.2.1 flag_3.3.3.2.2 flag_3.3.3.3.1  
1          718v  2019-08-14            NaN      3.3.3.2.2      3.3.3.3.1
2          566m  2019-07-10            NaN            NaN            NaN
3          636p  2019-06-12      3.3.3.2.1            NaN      3.3.3.3.1
4          630r  2019-06-30            NaN            NaN            NaN
26815      066p  2019-08-24      3.3.3.2.1      3.3.3.2.2      3.3.3.3.1
26816      769b  2019-08-10            NaN            NaN            NaN
方法1:

试试bfill和.iloc

方法2:

另一个解决方案是在notna上使用numpy argmax并将结果传递给lookup

注:输出基于此示例

In [83]: df

Out[83]:
      id_number   createdat flag_3.3.3.2.1 flag_3.3.3.2.2 flag_3.3.3.3.1  
1          718v  2019-08-14            NaN      3.3.3.2.2      3.3.3.3.1
2          566m  2019-07-10            NaN            NaN            NaN
3          636p  2019-06-12      3.3.3.2.1            NaN      3.3.3.3.1
4          630r  2019-06-30            NaN            NaN            NaN
26815      066p  2019-08-24      3.3.3.2.1      3.3.3.2.2      3.3.3.3.1
26816      769b  2019-08-10            NaN            NaN            NaN
我的解决办法是:

将包含列表的列转换为数据帧 每个元件的pd系列。 将基于第一个有效索引的函数应用于每一行。 假设df为:

定义以下功能:

def func(x):
    ind = x.first_valid_index()
    return None if ind is None else x[ind]
然后应用它:

df.flagging.apply(pd.Series).apply(func, axis=1)
我的解决办法是:

将包含列表的列转换为数据帧 每个元件的pd系列。 将基于第一个有效索引的函数应用于每一行。 假设df为:

定义以下功能:

def func(x):
    ind = x.first_valid_index()
    return None if ind is None else x[ind]
然后应用它:

df.flagging.apply(pd.Series).apply(func, axis=1)

的确,我可以在函数中使用列表理解,然后应用它生成预期的输出。谢谢的确,我可以在函数中使用列表理解,然后应用它生成预期的输出。谢谢谢谢,我代表我做了一个小的修改,它功能齐全!谢谢,我代表我做了一个小的修改,它功能齐全!