标记熊猫时间序列中的重复条目

Posted

技术标签:

【中文标题】标记熊猫时间序列中的重复条目【英文标题】:Flag repeating entries in pandas time series 【发布时间】:2020-04-24 04:24:55 【问题描述】:

我有一个采用这种形式的数据框(但有几百万行):

import pandas as pd     
dict = 'id':["A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D"], 
    'year': ["2000", "2001", "2002", "2000", "2001", "2003", "1999", "2000", "2001", "2000", "2000", "2001"],
    'vacation':["France", "Morocco", "Morocco", "Germany", "Germany", "Germany", "Japan", "Australia", "Japan", "Canada", "Mexico", "China"],
    'new':[1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1] 
df = pd.DataFrame(dict)

A   2000    France
A   2001    Morocco
A   2002    Morocco
B   2000    Germany
B   2001    Germany
B   2003    Germany
C   1999    Japan
C   2000    Australia
C   2001    Japan
D   2000    Canada       
D   2000    Mexico       
D   2001    China        

对于每一年的每个人,都会给出度假目的地;一年中可以有多个度假目的地。 当参与者去一个他们前一年没有去过的目的地(即目的地是新的)去度假时,我想标记这些行。在上述情况下,输出将是:

id  year    vacation    new
A   2000    France       1
A   2001    Morocco      1
A   2002    Morocco      0
B   2001    Germany      1
B   2002    Germany      0
B   2003    Germany      0
C   1999    Japan        1
C   1999    Australia    1
C   2000    Japan        1
D   2000    Canada       1
D   2000    Mexico       1
D   2001    China        1

对于 A、B、C 和 D,我们数据框中的第一个度假目的地被标记为新的。当 A 连续两年去摩洛哥时,没有标记第二次出现,因为 A 前一年去了那里。当 B 连续 3 次去德国时,不标记第 2 次和第 3 次。当人 C 两次去日本时,所有的事件都被标记,因为他们没有连续两年去日本 。 D 去了 3 个不同的目的地(尽管在 2000 年去了 2 个目的地)并且所有这些目的地都被标记了。

我一直在尝试自己解决这个问题,但一直无法摆脱迭代,对于如此庞大的数据集而言,迭代计算量太大。

我将不胜感激;谢谢。

【问题讨论】:

【参考方案1】:

IIUC,

我们正在做的是按idvacation 进行分组,并确保该年份不等于上面的年份,或者我们可以选择该组合的第一个实例。

希望这很清楚。如果您需要更多帮助,请告诉我。

df["new_2"] = (
    df.groupby(["id", "vacation"])["id", "year"]
    .apply(lambda x: x.ne(x.shift()))
    .all(axis=1)
    .add(0)
)

print(df)
  id  year   vacation  new_2
0  A  2000     France    1
1  A  2001        USA    1
2  A  2002     France    0
3  B  2001    Germany    1
4  B  2002    Germany    0
5  B  2003    Germany    0
6  C  1999      Japan    1
7  C  2000  Australia    1
8  C  2001     France    1

【讨论】:

这更好,+1! @anky_91 大错特错 =( ! 谢谢。我了解 groupby 做什么以及 neshift 单独做什么。不过,我很难理解正在比较的行。 @Logos24 什么不清楚?你可以删除每一层并单步执行代码,首先删除.ne.shift() 我现在明白了;值得补充的是,数据框必须按“年份”列升序排列才能正常工作。【参考方案2】:

这是我想出的一个解决方案,使用 groupby 和 transform:

df = df.sort_values(["id", "vacation", "year"])
df["new"] = (
    df.groupby(["id", "vacation"])
    .transform(lambda x: x.iloc[0])
    .year.eq(df.year)
    .astype(int)
)

你会得到

  id  year   vacation  new
0  A  2000     France    1
1  A  2001        USA    1
2  A  2002     France    0
3  B  2001    Germany    1
4  B  2002    Germany    0
5  B  2003    Germany    0
6  C  1999      Japan    1
7  C  2000  Australia    1
8  C  2001     France    1

【讨论】:

你不能改用transform('first') 吗?【参考方案3】:

这是一种使用groupby+cumcountseries.mask的方法:

df['new']=df.groupby(['id','vacation']).cumcount().add(1).mask(lambda x: x.gt(1),0)
print(df)

  id  year   vacation  new
0  A  2000     France    1
1  A  2001        USA    1
2  A  2002     France    0
3  B  2001    Germany    1
4  B  2002    Germany    0
5  B  2003    Germany    0
6  C  1999      Japan    1
7  C  2000  Australia    1
8  C  2001     France    1

【讨论】:

不知道你可以将.add() 与布尔值一起使用,你刚刚教了我一些新东西! @Datanovice cumcount 将返回一系列计数 :) 但是是的,您可以将它们链接起来 我总是忘记 cumcount 如何与 series 一起工作,无论如何我在使用 .any() 后无法与 groupby 一起工作 @Datanovice 是的,因为它只适用于 groupby 对象。 any 将返回一个系列

以上是关于标记熊猫时间序列中的重复条目的主要内容,如果未能解决你的问题,请参考以下文章

groupby 并获得出现率最高的熊猫条目[重复]

在没有聚合的熊猫数据透视表中重复条目并重命名列行

将包含列表的列拆分为熊猫中的不同行[重复]

获取熊猫数据框列表条目中的数字条目

Groupby - 具有重复值的熊猫 df 计数

熊猫数据框中的行排序和聚合