把Pandas群交给别人

2024-09-28 18:54:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个关于“其他”分组语法的问题。例如

测向

Type  Start  End Count Total
A     x      a   1     3
A     x      b   1     3
A     x      c   1     3
A     y      A   2     4
A     y      b   1     4
A     y      c   1     4
B     x      A   1     6
B     x      b   2     6
B     x      c   3     6
B     y      a   3     6
B     y      b   2     6
B     y      c   1     6

按类型/开始/结束列分组,如果结束不包含“a”或“a”,则将其标记为“其他”

Type  Start  End   Count Total
A     x      a     1     3
A     x      other 2     3
A     y      A     2     4
A     y      other 2     4
B     x      A     1     6
B     x      other 5     6
B     y      a     3     6
B     y      other 3     6

Tags: 标记typecount语法startendtotal按类型
3条回答

我认为您需要将所有不包含aAother的值替换为^{},将条件替换为^{},然后按列和序列使用groupby

s = df['End'].where(df['End'].isin(['a','A']), 'other')
print (s)
0         a
1     other
2     other
3         A
4     other
5     other
6         A
7     other
8     other
9         a
10    other
11    other
Name: End, dtype: object    

df = (df.groupby(['Type', 'Start', s])
        .agg({'Count':'sum', 'Total':'mean'})
        .reset_index())

另一个类似的解决方案是替换列End,并将原始解决方案用于groupby+agg

df['End'] = np.where(df['End'].isin(['a','A']), df['End'], 'other')
#alternatively
#df['End'] = df['End'].where(df['End'].isin(['a','A']), 'other')
df = (df.groupby(['Type', 'Start', 'End'], as_index=False)
        .agg({'Count':'sum', 'Total':'mean'}))

print (df)
  Type Start    End  Count  Total
0    A     x      a      1      3
1    A     x  other      2      3
2    A     y      A      2      4
3    A     y  other      2      4
4    B     x      A      1      6
5    B     x  other      5      6
6    B     y      a      3      6
7    B     y  other      3      6

你差点就到了。groupby的前两个参数很好,但最后一个需要修改。你知道吗

f = {'Count': 'sum', 'Total' : 'mean'}   
v = df.End.where(df.End.isin(['a', 'A']), 'other')

df.groupby(['Type', 'Start', v]).agg(f).reset_index()

  Type Start    End  Total  Count
0    A     x      a      3      1
1    A     x  other      3      2
2    A     y      A      4      2
3    A     y  other      4      2
4    B     x      A      6      1
5    B     x  other      6      5
6    B     y      a      6      3
7    B     y  other      6      3

细节

使用where/mask相应地改变df.End的值

v = df.End.where(df.End.isin(['a', 'A']), 'other')

或者

v = df.End.mask(~df.End.isin(['a', 'A']), 'other')

v

0         a
1     other
2     other
3         A
4     other
5     other
6         A
7     other
8     other
9         a
10    other
11    other
Name: End, dtype: object

或者,将列小写并比较。你知道吗

v = df.End.where(df.End.str.lower().eq('a'), 'other')

其余的,正如他们所说,是历史。如果您对保持列顺序感兴趣,请在末尾使用reindex调用。你知道吗

df.groupby(['Type', 'Start', v])\
  .agg(f)\
  .reset_index()\
  .reindex(columns=df.columns.tolist())

  Type Start    End  Count  Total
0    A     x      a      1      3
1    A     x  other      2      3
2    A     y      A      2      4
3    A     y  other      2      4
4    B     x      A      1      6
5    B     x  other      5      6
6    B     y      a      3      6
7    B     y  other      3      6

您可以更改End中条目的值以反映所需的更改,并使用前面描述的groupby。你知道吗

df.loc[~df.End.isin(['A', 'a']), 'End'] = 'other'
df.groupby(['Type','Start','End'']).agg({'Count':'sum','Tota‌​l':'mean'})

相关问题 更多 >