【发布时间】:2021-09-21 07:00:33
【问题描述】:
我有一个来自Pandas: conditional rolling count 的问题。我想在数据框中创建一个新列,以反映满足多个条件的行的累积计数。
使用以下示例和来自 stackoverflow 25119524 的代码
import pandas as pd
l1 =["1", "1", "1", "2", "2", "2", "2", "2"]
l2 =[1, 2, 2, 2, 2, 2, 2, 3]
l3 =[45, 25, 28, 70, 95, 98, 120, 80]
cowmast = pd.DataFrame(list(zip(l1, l2, l3)))
cowmast.columns =['Cow', 'Lact', 'DIM']
def rolling_count(val):
if val == rolling_count.previous:
rolling_count.count +=1
else:
rolling_count.previous = val
rolling_count.count = 1
return rolling_count.count
rolling_count.count = 0 #static variable
rolling_count.previous = None #static variable
cowmast['xmast'] = cowmast['Cow'].apply(rolling_count) #new column in dataframe
cowmast
输出是每头奶牛的 xmast(乳腺炎次数)
Cow Lact DIM xmast 0 1 1 45 1 1 1 2 25 2 2 1 2 28 3 3 2 2 70 1 4 2 2 95 2 5 2 2 98 3 6 2 2 120 4 7 2 3 80 5我想做的是重新开始对每头奶牛 (cow) 泌乳 (Lact) 的计数,并且仅在行之间的天数 (DIM) 超过 7 时才增加计数。
为了合并多个条件来重置每头奶牛泌乳 (Lact) 的计数,我使用了以下代码。
def count_consecutive_items_n_cols(df, col_name_list, output_col):
cum_sum_list = [
(df[col_name] != df[col_name].shift(1)).cumsum().tolist() for col_name in col_name_list
]
df[output_col] = df.groupby(
["_".join(map(str, x)) for x in zip(*cum_sum_list)]
).cumcount() + 1
return df
count_consecutive_items_n_cols(cowmast, ['Cow', 'Lact'], ['Lxmast'])
产生以下输出
Cow Lact DIM xmast Lxmast 0 1 1 45 1 1 1 1 2 25 2 1 2 1 2 28 3 2 3 2 2 70 1 1 4 2 2 95 2 2 5 2 2 98 3 3 6 2 2 120 4 4 7 2 3 80 5 1我希望了解如何在累积计数中添加另一个条件,该条件考虑到乳腺炎事件之间的时间(同一 Lact 内奶牛的行之间的 DIM 差异)。如果同一头奶牛和泌乳行之间的 DIM 差异小于 7,则计数不应增加。
我正在寻找的输出在下表中称为“已调整”。
Cow Lact DIM xmast Lxmast 已调整 0 1 1 45 1 1 1 1 1 2 25 2 1 1 2 1 2 28 3 2 1 3 2 2 70 1 1 1 4 2 2 95 2 2 2 5 2 2 98 3 3 2 6 2 2 120 4 4 3 7 2 3 80 5 1 1在上述奶牛 1 lact 2 的示例中,当昏暗从 25 变为 28 时,计数不会增加,因为这两个事件之间的差异小于 7 天。奶牛 2 lact 2 从 95 到 98 时也是如此。对于较大的增量,从 70 到 95 和从 98 到 120,计数会增加。
感谢您的帮助
约翰
【问题讨论】:
-
请包括您的预期输出并尝试改写您的问题,不清楚您想要什么。
-
感谢弗兰克的反馈,希望我的编辑和示例能让它更清晰。约翰