Pandas Dataframe,应用函数,返回索引

时间:2013-09-24 00:06:28

标签: python numpy pandas

我有一个数据框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

1 个答案:

答案 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)进行转换。