在数据框(熊猫)中查找每月重复值

时间:2020-03-05 10:46:46

标签: python pandas dataframe time-series python-3.6

因此,我有一个数据集,其中包含日期和值(对应于这些日期)。

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)])]

任何帮助将不胜感激。

3 个答案:

答案 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))