Python 筛选列表中与每行的条件匹配的第一个元素
问题/问题:我想创建另一列,该列包含列表中多个/或值的第一列,该列表符合不同于nan的条件 我正在研究一个数据帧,它有多个列作为标志,每一列都是一种不同的标志。这就是它看起来的样子: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.
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)
的确,我可以在函数中使用列表理解,然后应用它生成预期的输出。谢谢的确,我可以在函数中使用列表理解,然后应用它生成预期的输出。谢谢谢谢,我代表我做了一个小的修改,它功能齐全!谢谢,我代表我做了一个小的修改,它功能齐全!