【问题标题】:Pandas Dataframe, Apply Function, Return IndexPandas 数据框、应用函数、返回索引
【发布时间】:2013-09-24 00:06:28
【问题描述】:

我有一个数据框 df,它有两列:ID 和日期。它记录不同日期的 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 有第二条记录,并且没有第三条记录,它仍然在第二条记录。有人可以帮助正确的符号吗?

(注意:考虑到我的数据集,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

【问题讨论】:

  • 您能否发布您的框架样本和预期输出?

标签: python numpy pandas


【解决方案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) 来转换它们。

【讨论】:

  • 真的很聪明,而且效果很好。谢谢。但是,如果我只是想知道该 ID 在接下来的 3000 天内是否还有另一个日期,该怎么办。有没有办法让我的功能正常工作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 2022-01-16
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 2019-09-05
相关资源
最近更新 更多