在Python中,如何像R一样通过+ mutate + ifelse进行分组?

时间:2018-04-23 04:13:22

标签: python transform mutate

我通常使用R.如果我有这样的数据:

Product    Index   Value
   a         1       0.5
   a         1       0.4
   c         1       1.4
   c         2       0.75
   e         2       0.6
   f         3       0.9

如果我的R代码是:

a <- data %>%
  group_by(Product) %>%
  mutate(Flag=ifelse(all(Index==1),'right','wrong'))

这意味着,我首先按产品对数据进行分组。然后对于每个组,我将给它一个名为Flag的新字段。如果此组中的索引全部为1,则Flag为正确,否则为错误。与此同时,所有的reocrds仍然存在。所以,结果应该是这样的:

Product    Index   Value    Flag
   a         1       0.5    right
   a         1       0.4    right
   c         1       1.4    wrong
   c         2       0.75   wrong
   e         2       0.6    wrong
   f         3       0.9    wrong

我的问题是:如何在python中执行相同的操作?我试过,np.where,groupby,transform等功能。我可能以错误的方式组合它们。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:4)

使用变换是一种选择。

import pandas as pd

df = pd.DataFrame({'Product': ['a', 'a', 'c', 'c', 'e', 'f'],
               'Index': [1, 1, 1, 2, 2, 3], 
              'Value': [0.5, 0.4, 1.4, 0.75, 0.6, 0.9]})
df['Flag'] = df.groupby('Product')['Index'].transform(lambda x: 'right' if sum(x)/len(x) == 1 else 'wrong')
df

另一方面,如果标志值只是“正确”的话。和&#39;错误&#39;用0,1值代替它们可能更有效。

答案 1 :(得分:2)

您可以使用unique()groupby()来确保所有商品的索引均为1,然后映射到新列:

In [51]: df['Flag'] = df['Product'].map(df.groupby('Product')['Index'].unique().apply(lambda row: 'right' if all(row==[1]) else 'wrong'))

In [52]: df
Out[52]:
  Product  Index  Value   Flag
0       a      1   0.50  right
1       a      1   0.40  right
2       c      1   1.40  wrong
3       c      2   0.75  wrong
4       e      2   0.60  wrong
5       f      3   0.90  wrong

答案 2 :(得分:1)

GroupBy.transformmean一起使用,按1numpy.where与条件进行比较:

df['Flag'] = np.where(df.groupby('Product')['Index'].transform('mean')== 1, 'right', 'Wrong')
print (df)
  Product  Index  Value   Flag
0       a      1   0.50  right
1       a      1   0.40  right
2       c      1   1.40  Wrong
3       c      2   0.75  Wrong
4       e      2   0.60  Wrong
5       f      3   0.90  Wrong

<强>详细

print (df.groupby('Product')['Index'].transform('mean'))
0    1.0
1    1.0
2    1.5
3    1.5
4    2.0
5    3.0
Name: Index, dtype: float64

另一种解决方案:

首先按1eq然后GroupBy.transformall进行比较,以检查每个组是否Truenumpy.where按条件:

df['Flag'] = np.where(df['Index'].eq(1).groupby(df['Product']).transform('all'), 
                      'right', 'Wrong')
print (df)
  Product  Index  Value   Flag
0       a      1   0.50  right
1       a      1   0.40  right
2       c      1   1.40  Wrong
3       c      2   0.75  Wrong
4       e      2   0.60  Wrong
5       f      3   0.90  Wrong

<强>详细

print (df['Index'].eq(1).groupby(df['Product']).transform('all'))
0     True
1     True
2    False
3    False
4    False
5    False
Name: Index, dtype: bool