因此,我有一个数据集,其中包含日期和值(对应于这些日期)。
date value category
1951-07 199 1
1951-07 130 3
1951-07 50 5
1951-08 199 1
1951-08 50 5
1951-08 199 1
1951-09 184 2
1951-09 50 5
1951-09 13 13
现在我的目标是找到每个月重复的值。 结果是这样的帧:
date value category
1951-07 50 5
1951-08 50 5
1951-09 50 5
也不要考虑一个月内重复出现的值,或者只重复几个月而不是全部重复的值。
类别通常与值相匹配(如示例中所示),但有时却没有。因此,我尝试按类别进行操作,但没有得到确切的结果。
我当前的方法是过滤重复项,然后将其重复出现12次(因为我每年都在搜索)。但这也给了我价值,一个月内可以重复12次。
df = df[df.duplicated(['value'],keep=False)]
v = df.value.value_counts()
df_12 = df[df.value.isin(v.index[v.gt(12)])]
任何帮助将不胜感激。
答案 0 :(得分:3)
我将首先按值分组并删除日期上的重复项:
tmp = df.groupby('value')['date'].apply(lambda x: x.drop_duplicates())
您的样本将给出:
value
13 8 1951-09
50 2 1951-07
4 1951-08
7 1951-09
130 1 1951-07
184 6 1951-09
199 0 1951-07
3 1951-08
Name: date, dtype: object
然后我们可以安全地计算值,并仅保留具有预期计数的值:
total = tmp.groupby(level=0).count()
total = total[total == 3]
我们得到:
value
50 3
Name: date, dtype: int64
我们可以最终过滤原始数据帧:
df[df['value'].isin(total.index)]
符合预期:
date value category
2 1951-07 50 5
4 1951-08 50 5
7 1951-09 50 5
根据Jezrael的评论,构建total
的第一步应该变成:
total = df.drop_duplicates(['date', 'value'])[['date', 'value']
].groupby('value').count()['date']
total = total[total == 3]
它既简单又快速...
答案 1 :(得分:1)
这是一种透视和检查all
行在notna
位置的方式:
piv = df.pivot_table(index='date', columns='category', values='value', aggfunc='first')
df[df.category.eq(piv.notna().all(0).idxmax())]
date value category
2 1951-07 50 5
4 1951-08 50 5
7 1951-09 50 5
位置:
print(piv)
category 1 2 3 5 13
date
1951-07 199.0 NaN 130.0 50.0 NaN
1951-08 199.0 NaN NaN 50.0 NaN
1951-09 NaN 184.0 NaN 50.0 13.0
答案 2 :(得分:1)
首先获取副本
df_dups = df[df.duplicated(subset=['value', 'category'], keep=False)]
然后删除仅在一个月内重复的内容,即
df_dups = df_dups.groupby(['value', 'category']).filter(lambda g: g['date'].nunique() > 1)
您还可以删除结果表中的重复项,即
df_dups = df_dups.groupby(['value', 'category']).apply(lambda g: g.drop_duplicates('date', keep='last))