我有一个数据框df,有两列:ID和Dates。它记录不同日期的ID事件。这两个字段都不是唯一的,但行组合是唯一的(没有ID在同一日期有多个记录)。
我有以下功能来添加一个新列,以便在给定的记录/日期确定ID是否在以后的日期有另一条记录(TRUE / FALSE):
def f(df):
count = pd.Series(np.arange(1, len(df)+1), index=df["date"])
day = count.index.shift(0, freq="D")
next18month = count.index.shift(3000, freq="D")
result = count.asof(next18month).fillna(0).values - count.asof(day).fillna(0).values
if result[0] > 0:
return pd.Series(1, df.index)
else:
return pd.Series(0, df.index)
然后我可以将该函数应用于我的数据帧,按ID分组:
df["everagain"] = df.groupby("id").apply(f)
它不起作用。我相信result[0]
是错误的。它首次出现ID(它第二次计数,跳过一个真正的返回),但如果给定id的第二个记录,没有第三个记录,它仍然返回'1'(True)at第二条记录。有人可以帮助使用正确的符号吗?
(注意:根据我的数据集,3000天就足够了。)
例如,如果df看起来像:
| ID | Date
0 | A | 2010-01-01
1 | A | 2010-02-01
2 | A | 2010-02-15
3 | B | 2010-01-01
4 | C | 2010-02-01
5 | C | 2010-02-15
然后输出有望看起来像:
| ID | Date | everagain
0 | A | 2010-01-01 | 1
1 | A | 2010-02-01 | 1
2 | A | 2010-02-15 | 0
3 | B | 2010-01-01 | 0
4 | C | 2010-02-01 | 1
5 | C | 2010-02-15 | 0
答案 0 :(得分:1)
我原本以为我可以使用.groupby("ID").last()
但是无法让它发挥作用。 (当然,我们可以用transform
做到这一点,但这感觉太火了。)
如果您的数据按date
排序且具有连续的ID,则可以简单地比较ID
是否等于下一个ID
。例如:
>>> df = df.sort(["ID", "Date"])
>>> df
ID Date
0 A 2010-01-01 00:00:00
1 A 2010-02-01 00:00:00
2 A 2010-02-15 00:00:00
3 B 2010-01-01 00:00:00
4 C 2010-02-01 00:00:00
5 C 2010-02-15 00:00:00
>>> df["everagain"] = df["ID"] == df["ID"].shift(-1)
>>> df
ID Date everagain
0 A 2010-01-01 00:00:00 True
1 A 2010-02-01 00:00:00 True
2 A 2010-02-15 00:00:00 False
3 B 2010-01-01 00:00:00 False
4 C 2010-02-01 00:00:00 True
5 C 2010-02-15 00:00:00 False
如果您想要的是1和0而不是True and False
,则可以使用(df["ID"] == df["ID"].shift(-1))*1)
或(df["ID"] == df["ID"].shift(-1)).astype(int)
进行转换。