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

Python 在数据帧中查找每月重复值(熊猫),python,pandas,dataframe,time-series,python-3.6,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

所以我有一个数据集,其中包括日期和值,对应于这些日期

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

任何帮助都将不胜感激。

这里有一个单向旋转和检查
所有
行的位置
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

先把复制品拿出来

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

我将首先按值分组并删除日期上的重复项:

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]

它既简单又快速…

@jezrael:谢谢你的提醒!我一步一步地进行,但没有意识到:-(@jezrael:我已经用你的评论编辑了我的帖子。再次感谢你…编辑后的代码确实留下了一些值,这些值只出现一次。对于我的数据集,第一种方法工作得更可靠。最后一行导致一个错误:DataFrameGroupBy'object has no attribute'drop_duplicates'