【发布时间】:2021-12-06 16:47:02
【问题描述】:
这是我的数据框的简化版本:
d = {'col1': ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3', 'd1', 'd2', 'd3'], 'col2': [1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1], 'col3': [-1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1]}
df = pd.DataFrame(d)
df
col1 col2 col3
0 a1 1 -1
1 a2 1 -1
2 a3 1 1
3 b1 -1 -1
4 b2 -1 -1
5 b3 -1 1
6 c1 -1 1
7 c2 1 1
8 c3 1 1
9 d1 -1 -1
10 d2 1 -1
11 d3 1 1
我希望能够只提取那些在col3 == 1 第一次 n 在col2 == 1 第一次之后的行,每个字母组。
例如,如果我们在 col2 变为 1(对于每个字母组)之后寻找 col3 变为 1 一行的时间,我们将得到
col1 col2 col3
0 d3 1 1
因为对于组 d,col2 在 d2 时从 -1 变为 1,而 col3 在 d3 时从 -1 变为 1。而这在任何其他群体中都没有发生过。
如果我们想要 col3 变为 1 的行 两行 在 col2 变为 1 之后(对于每个字母组),我们将得到
col1 col2 col3
0 a3 1 1
因为对于组 a,col2 在 a1 处从 1 开始,而 col3 在 a3 处从 -1 变为 1。
编辑:
这是我尴尬的做法……有人有更优雅的解决方案吗?
df['newCol'] = (
(((df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1)) &
(df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1))) |
(df['col1'].shift(n+1).str[0] != df['col1'].str[0])) &
(df['col2'].shift(n) == 1) &
(df['col3'].shift(n) == -1) &
(df['col2'].shift(1) == 1) &
(df['col3'].shift(1) == -1) &
(df['col2'] == 1) &
(df['col3'] == 1) &
(df['col1'].shift(n).str[0] == df['col1'].str[0])) if n > 0 \
else \
((((df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1)) &
(df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1))) |
(df['col1'].shift(n+1).str[0] != df['col1'].str[0])) &
(df['col2'] == 1) &
(df['col3'] == 1))
【问题讨论】:
-
col1 是你的标签,你的意思是 col2beame 1 之后?
-
@QuangHoang 抱歉,是的,刚刚修好了
-
我建议阅读一些关于如何过滤数据帧的 Pandas 文档。您将能够相对较快地回答这个问题。
-
@mrp 我知道如何进行基本过滤。然而,我发现这是一个挑战。
-
一种可能更高效的方法是使用
shift()创建一个滞后于条件列的新列。因此,您可以在数组上使用 pandas 标准过滤器进行过滤,如果您的数据框非常大,这将更快。
标签: python pandas dataframe filter