向量化方法,arange
用于查找最后一个索引max
、 和连接:
df['last_referred'] = np.r_[[np.NaN], df.columns][
((df == 'referred') * (np.arange(df.shape[1]) + 1)).max(axis=1).values]
解释:
我们想在每一行中找到最右边的具有值的单元格'referred'
:
>>> df == 'referred'
name action_1 action_2 action_3
0 False True True False
1 False False True True
2 False False False False
3 False False True False
4 False True False False
5 False False False False
一个选项是DataFrame.idxmax
,但这给出了第一个(即最左边的)出现。但是,假设我们可以True
用它们的列索引替换这些值,我们可以只使用 normal max
。由于True
is1
和False
is 0
,我们可以通过乘以[0, 1, 2, ...]
垂直广播的整数范围来做到这一点:
>>> np.arange(df.shape[1])
array([0, 1, 2, 3])
>>> (df == 'referred') * np.arange(df.shape[1])
name action_1 action_2 action_3
0 0 1 2 0
1 0 0 2 3
2 0 0 0 0
3 0 0 2 0
4 0 1 0 0
5 0 0 0 0
>>> ((df == 'referred') * np.arange(df.shape[1])).max(axis=1)
0 2
1 3
2 0
3 2
4 1
5 0
dtype: int32
但是有一个问题:我们无法区分'referred'
“名称”列和根本不出现之间的区别。易于修复;只需从 1 开始整数范围:
>>> ((df == 'referred') * (np.arange(df.shape[1]) + 1)).max(axis=1)
0 3
1 4
2 0
3 3
4 2
5 0
dtype: int32
现在只需使用这个数组来索引列名:
>>> df.columns[((df == 'referred') * (np.arange(df.shape[1]) + 1)).max(axis=1).values]
IndexError: index 4 is out of bounds for size 4
哎呀!我们需要制作0
出来,NaN
其余的列要转移。我们可以使用np.r_
连接数组来做到这一点:
>>> np.r_[[np.NaN], df.columns]
array([nan, 'name', 'action_1', 'action_2', 'action_3'], dtype=object)
>>> np.r_[[np.NaN], df.columns][
((df == 'referred') * (np.arange(df.shape[1]) + 1)).max(axis=1).values]
array(['action_2', 'action_3', nan, 'action_2', 'action_1', nan], dtype=object)
你有它。