根据其他行的值有条件地标记数据框中的行
flag rows in a dataframe conditionally on values of other rows
考虑数据帧df_in = pd.DataFrame({'id': [0,1,2,2,3,4,4,4], 'channel': [0,1,0,1,3,2,3,1]})
> df_in
id channel
0 0 0
1 1 1
2 2 0
3 2 1
4 3 3
5 4 2
6 4 3
7 4 1
和一个 2 元组列表 allowed_channel_couples = ((0,1),(2,3))
。
我想获取一个新的数据框 df_out
作为:
id channel flag
0 0 0 0
1 1 1 0
2 2 0 1
3 2 1 1
4 3 3 0
5 4 2 1
6 4 3 1
7 4 1 0
df_out
中的每一行等于 df_in
中的行。但是,df_out
包含一个名为 flag
的新列。 df_out
中某行的 flag
值等于 1 仅当存在具有相同 id
的另一行时,其通道值 'matches' 第一行的通道值,根据 allowed_channel_couples
.
因此考虑 df_in
中索引为 5 的行。该行 id
等于 4,channel
等于 2。由于索引 6 处的行 id
等于 4,channel
值等于 3,因此 (2,3)
是在 allowed_channel
中,索引为 5 的行和索引为 6 的行都标有标志 1
。
另一方面,df_in
的索引为 7 的行有 id
等于 4,channel
等于 1。在这种情况下允许标记的对是 (0,1)
。 id
等于 4 且通道等于 0 的其他行不存在,因此索引为 7 的行标记为 0.
我在解决这个避免 python 慢循环的问题时遇到了麻烦。关于如何有效地获取标志列的任何想法?
想法:
- 我试过使用
agg
方法。因此,我能够获得 table,例如:
id channel
0 0 [0]
1 1 [1]
2 2 [0, 1]
3 3 [3]
4 4 [2, 3, 1]
到 df_in.groupby('id', as_index=False).agg({'channel': lambda x: tuple(x)})
.
您可以将值从一个元组值映射到另一个元组值,然后识别重复值:
d = dict(allowed_channel_couples)
# {0: 1, 2: 3}
df_in['flag'] = (df_in
.assign(channel=df_in['channel'].map(d).fillna(df_in['channel']))
.duplicated(['id', 'channel'], keep=False)
.astype(int)
)
输出:
id channel flag
0 0 0 0
1 1 1 0
2 2 0 1
3 2 1 1
4 3 3 0
5 4 2 1
6 4 3 1
7 4 1 0
考虑数据帧df_in = pd.DataFrame({'id': [0,1,2,2,3,4,4,4], 'channel': [0,1,0,1,3,2,3,1]})
> df_in
id channel
0 0 0
1 1 1
2 2 0
3 2 1
4 3 3
5 4 2
6 4 3
7 4 1
和一个 2 元组列表 allowed_channel_couples = ((0,1),(2,3))
。
我想获取一个新的数据框 df_out
作为:
id channel flag
0 0 0 0
1 1 1 0
2 2 0 1
3 2 1 1
4 3 3 0
5 4 2 1
6 4 3 1
7 4 1 0
df_out
中的每一行等于 df_in
中的行。但是,df_out
包含一个名为 flag
的新列。 df_out
中某行的 flag
值等于 1 仅当存在具有相同 id
的另一行时,其通道值 'matches' 第一行的通道值,根据 allowed_channel_couples
.
因此考虑 df_in
中索引为 5 的行。该行 id
等于 4,channel
等于 2。由于索引 6 处的行 id
等于 4,channel
值等于 3,因此 (2,3)
是在 allowed_channel
中,索引为 5 的行和索引为 6 的行都标有标志 1
。
另一方面,df_in
的索引为 7 的行有 id
等于 4,channel
等于 1。在这种情况下允许标记的对是 (0,1)
。 id
等于 4 且通道等于 0 的其他行不存在,因此索引为 7 的行标记为 0.
我在解决这个避免 python 慢循环的问题时遇到了麻烦。关于如何有效地获取标志列的任何想法?
想法:
- 我试过使用
agg
方法。因此,我能够获得 table,例如:
id channel
0 0 [0]
1 1 [1]
2 2 [0, 1]
3 3 [3]
4 4 [2, 3, 1]
到 df_in.groupby('id', as_index=False).agg({'channel': lambda x: tuple(x)})
.
您可以将值从一个元组值映射到另一个元组值,然后识别重复值:
d = dict(allowed_channel_couples)
# {0: 1, 2: 3}
df_in['flag'] = (df_in
.assign(channel=df_in['channel'].map(d).fillna(df_in['channel']))
.duplicated(['id', 'channel'], keep=False)
.astype(int)
)
输出:
id channel flag
0 0 0 0
1 1 1 0
2 2 0 1
3 2 1 1
4 3 3 0
5 4 2 1
6 4 3 1
7 4 1 0