Python 计算某个值出现之间的行数

Python 计算某个值出现之间的行数,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,首先,我不确定我的措辞是否正确,这可能就是为什么我没有在网上找到解决方案的原因 我有一个示例数据帧,由以下代码生成: import pandas as pd import numpy as np data1 = list(np.arange(24)) * 2 data2 = ['A'] * 24 + ['B'] * 24 data3 = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,

首先,我不确定我的措辞是否正确,这可能就是为什么我没有在网上找到解决方案的原因

我有一个示例数据帧,由以下代码生成:

import pandas as pd
import numpy as np

data1 = list(np.arange(24)) * 2
data2 = ['A'] * 24 + ['B'] * 24
data3 = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
         0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
  
df = pd.DataFrame(data=zip(data1, data2, data3), columns=['day', 'group',
                  'value'])

days_with_one = df.groupby('group').apply(lambda x: x.loc[df['value'] == 1,
                          'day'])
我想做的是,对于值为“1”的每一天,找出自上次值为“1”以来经过了多少天(分别针对每组)

我已经将df减少到只有值为1的行。因此,示例输出如下所示:

group  day    days_since
A      5       0
       10      5
       19      9
B      3       0
       13     10
       16      3
       20      4

首先,您可以通过compare by
1
by为组创建新列,这里如果存在一些
0
值,这意味着每个组在First
1
之前有一些值,因此使用First duplicated rows by和last use for difference进行过滤 每个组的repalce缺失值为
0

df['days_since'] = df['value'].eq(1).groupby(df['group']).cumsum()
mask = ~df.duplicated(['group', 'days_since']) & df['days_since'].ne(0)

df1 = df.loc[mask, ['group','day']].copy()
df1['days_since'] = df1.groupby('group')['day'].diff().fillna(0).astype(int)
print (df1)
   group  day  days_since
5      A    5           0
10     A   10           5
19     A   19           9
27     B    3           0
37     B   13          10
40     B   16           3
44     B   20           4
编辑:感谢@Henry Yik简化答案-您可以只筛选
value
1
的行,然后获得差异:

mask = df['value'].eq(1)
df1 = df.loc[mask, ['group','day']].copy()
df1['days_since'] = df1.groupby('group')['day'].diff().fillna(0).astype(int)
print (df1)
   group  day  days_since
5      A    5           0
10     A   10           5
19     A   19           9
27     B    3           0
37     B   13          10
40     B   16           3
44     B   20           4

首先,您可以通过compare by
1
by为组创建新列,这里如果存在一些
0
值,这意味着每个组在First
1
之前有一些值,因此使用First duplicated rows by和last use for difference进行过滤 每个组的repalce缺失值为
0

df['days_since'] = df['value'].eq(1).groupby(df['group']).cumsum()
mask = ~df.duplicated(['group', 'days_since']) & df['days_since'].ne(0)

df1 = df.loc[mask, ['group','day']].copy()
df1['days_since'] = df1.groupby('group')['day'].diff().fillna(0).astype(int)
print (df1)
   group  day  days_since
5      A    5           0
10     A   10           5
19     A   19           9
27     B    3           0
37     B   13          10
40     B   16           3
44     B   20           4
编辑:感谢@Henry Yik简化答案-您可以只筛选
value
1
的行,然后获得差异:

mask = df['value'].eq(1)
df1 = df.loc[mask, ['group','day']].copy()
df1['days_since'] = df1.groupby('group')['day'].diff().fillna(0).astype(int)
print (df1)
   group  day  days_since
5      A    5           0
10     A   10           5
19     A   19           9
27     B    3           0
37     B   13          10
40     B   16           3
44     B   20           4

那么你想要的预期结果是什么呢?那么你想要的预期结果是什么呢?使用
df.loc[df[“value”].eq(1)]
然后使用
groupby
diff
?@HenryYik-谢谢,你是对的,已经有了计数器列,那么你是对的。@jezrael为什么在这里使用
copy
呢?你不能只使用
drop
来删除列
?@ShubhamSharma-因为列的新顺序是
,所以在一个过滤器中删除并更改列的顺序。Hmm。有道理。使用
df.loc[df[“value”].eq(1)]
然后使用
groupby
diff
?@HenryYik-谢谢,你说得对,已经有计数器列了,那么你是对的。@jezrael为什么在这里使用
copy
呢?你不能只使用
drop
来删除列
?@ShubhamSharma-因为列的新顺序是
,所以在一个过滤器中删除并更改列的顺序。Hmm。有道理。