Python groupby值计数不等于其他列值
我的目标是通过groupby值计数,但只考虑Python groupby值计数不等于其他列值,python,pandas,group-by,Python,Pandas,Group By,我的目标是通过groupby值计数,但只考虑Item和Item 2不同的行。下面实现了这一点,但如果没有不同的值,则删除行。如果存在一个或多个值,但是Item和Item 2之间相同,那么我希望返回0 import pandas as pd df = pd.DataFrame({ 'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,4,4,4], 'Item' : ['A','A','A','A','A','A','A','B','B','B','
Item
和Item 2
不同的行。下面实现了这一点,但如果没有不同的值,则删除行。如果存在一个或多个值,但是Item
和Item 2
之间相同,那么我希望返回0
import pandas as pd
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,4,4,4],
'Item' : ['A','A','A','A','A','A','A','B','B','B','B','B','B','B','A','B','B','B'],
'Item2' : ['B','A','A','A','B','B','B','A','A','B','A','B','B','B','A','B','A','A'],
'Value' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5, 1, 2, 3],
})
df1 = df[df['Item'] != df['Item2']].groupby(['Time']).size().reset_index(name='count')
预期产出:
Time count
0 1 4
1 2 3
2 3 0
3 4 2
Time avg
0 1 3.0
1 2 5.0
2 3 0.0
3 4 2.5
编辑2:
df = pd.DataFrame({
'Time' : ['1','1','1','1','1','1','1','2','2','2','2','2','2','2','3','4','4','4'],
'Item' : ['A','A','A','A','A','A','A','B','B','B','B','B','B','B','A','B','B','B'],
'Item2' : ['B','A','A','A','B','B','B','A','A','B','A','B','B','B','A','B','A','A'],
'Value' : [2, 6, 6, 5, 3, 3, 4, 6, 5, 1, 4, 6, 7, 4, 5, 1, 2, 3],
})
df1 = (df.assign(new = df['Item'] != df['Item2'])
.groupby('Time')['new']
.mean()
.reset_index(name='avg')
)
预期产出:
Time count
0 1 4
1 2 3
2 3 0
3 4 2
Time avg
0 1 3.0
1 2 5.0
2 3 0.0
3 4 2.5
看一看熊猫的数据透视表
import pandas as pd
import numpy as np
df = pd.DataFrame({
'Time' : [1,1,1,1,1,1,1,2,2,2,2,2,2,2,3],
'Item' : ['A','A','A','A','A','A','A','B','B','B','B','B','B','B','A'],
'Item2' : ['B','A','A','A','B','B','B','A','A','B','A','B','B','B','A'],
'Value' : [5, 6, 6, 5, 5, 6, 5, 6, 3, 1, 4, 6, 7, 4, 5],
})
# this gives you just the ones were there is a differance
df2 = df[df['Item'] != df['Item2']]
# then sum up the numbers for each item
pd.pivot_table(df2,index='Time',aggfunc='count')
这是你的桌子
Item Item2 Value
Time
1 4 4 4
2 3 3 3
Idea不是过滤器,而是通过
sum
对每组True
s的计数值进行过滤,这里将系列df['Time']
传递给分组依据
:
df1 = (df['Item'] != df['Item2']).groupby(df['Time']).sum().reset_index(name='count')
print (df1)
Time count
0 1 4
1 2 3
2 3 0
3 4 2
另一个类似的解决方案是创建新的辅助列并将其聚合:
df1 = (df.assign(new = df['Item'] != df['Item2'])
.groupby('Time')['new']
.sum()
.reset_index(name='count'))
编辑:您可以将不匹配的值替换为misisng值,然后将misisng值替换为fillna
df1 = (df.assign(new = df['Value'].where(df['Item'] != df['Item2']))
.groupby('Time')['new']
.mean()
.fillna(0)
.reset_index(name='avg')
)
print (df1)
Time avg
0 1 3.0
1 2 5.0
2 3 0.0
3 4 2.5
备选方案由原始时间列的uniqu值使用:
df1 = (df[df['Item'] != df['Item2']]
.groupby(['Time'])['Value']
.mean()
.reindex(df['Time'].unique(), fill_value=0)
.reset_index(name='avg'))
抱歉@Paul Brennan,与我预期的输出不完全相同将aggfunc更改为“count”Yeh,我尝试删除行,但对于单个值,我需要返回一个0
。我可以先进行子集划分,然后对一个单独的数据进行计数,然后重新合并,但这似乎有点效率。有道理。只是一个简单的例子,如果我想用同样的条件得到一个平均值,那该如何应用呢?我已经做了一个快速编辑2。