如何获取Pandas中特定行之后满足条件的下一行的时间戳

vbkedwbf  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(121)

我得到了一个df,其中的't'列表示时间,'first'和'second'列(这里,为了简单起见,我在t列中使用了数字,但它们将是datetime对象或日期字符串)

t   first   second
1   grey    red
2   green   red
3   red     red
4   grey    green
5   green   red
6   grey    green
7   green   red
8   red     red

它可以像这样创建:

import pandas as pd

dfx = pd.DataFrame(
    {
        'time': [1,2,3,4,5,6,7,8],
        'first': ['grey', 'green', 'red', 'grey', 'green', 'grey', 'green', 'red'], 
        'second': ['red', 'red', 'red', 'green', 'red', 'green', 'red', 'red']
    }
)

我需要选择第一个等于绿色的行,然后添加第二个也等于绿色的行,得到的df如下所示:

t   first   t_second
2   green   4
5   green   6
7   green   NaN

我怎样才能做到这一点?
我发现了一个类似的问题here,但它处理布尔值。我不完全理解答案,但据我所知,它不工作在一个类似的方式与多个类别值。我也不能转换为布尔,因为我将有多个选项的颜色类别。

p5cysglq

p5cysglq1#

让我们先对second列进行one-hot编码:

>>> pd.get_dummies(df.set_index("t")["second"])

   green  red
t            
1      0    1
2      0    1
3      0    1
4      1    0
5      0    1
6      1    0
7      0    1
8      0    1

然后将greenred乘以t,这样我们就可以将t分解为greenred

>>> _ * df["t"].to_numpy()[:, None]

   green  red
t            
1      0    1
2      0    2
3      0    3
4      4    0
5      0    5
6      6    0
7      0    7
8      0    8

现在,如果我们用 * 下一个非零 * 值填充零,我们将得到所需的结果。

>>> # fill 0 with the next non-zero value #

   green  red
t            
1      4    1
2      4    2
3      4    3
4      4    5
5      6    5
6      6    7
7    nan    7
8    nan    8

这意味着从t = 1开始,green的下一次出现是在t = 4,我们现在只需要将其加入到原始 Dataframe 中就可以得到我们想要的结果。

代码:

tmp = (
    pd.get_dummies(df.set_index("t")["second"])
    .mul(df["t"].to_numpy()[:, None])
    .replace(0, np.nan)
    .bfill()
    .rename_axis(columns="second")
    .stack()
    .rename("t_second")
)

df.merge(tmp, how="left", left_on=["t", "first"], right_on=["t", "second"])

这里假设t != 0,实际数据很可能就是这种情况。

ny6fqffe

ny6fqffe2#

这是列的反向填充吗?
查找条件为真的值:

dfx.loc[dfx["second"] == "green", "t_second"] = dfx["time"]
time  first second  t_second
0     1   grey    red       NaN
1     2  green    red       NaN
2     3    red    red       NaN
3     4   grey  green       4.0
4     5  green    red       NaN
5     6   grey  green       6.0
6     7  green    red       NaN
7     8    red    red       NaN

反向填充:
一个二个一个一个
选择first绿色行:

dfx.loc[dfx["first"] == "green"]
time  first second  t_second
1     2  green    red       4.0
4     5  green    red       6.0
6     7  green    red       NaN

相关问题