首页 > 解决方案 > Pandas - 在特定值组的特定条件下将值变为负值

问题描述

我有一个看起来像这样的 df 示例:

   Group   0       1       Total      
0    1     Text    5        5
1    1     Text2   5        5
2    1     SUM     10       10
3    2     10%     10       10
4    2     100%    100      100
5    2     SUM     110      110
6    3     Text3   4        4
7    3     SUM     4        4

每行被分成组——在这种情况下,组从 1 到 3——组的数量是不同的,但这并不重要。

我希望df[0]数字和%符号中的所有元素(例如 10% 或 100%)将它们在Total列中的值更改为负值
这种解决方案的示例:

   Group   0       1       Total      
0    1     Text    5        5
1    1     Text2   5        5
2    1     SUM     10       10
3    2     10%     10       -10    <--- change the value here
4    2     100%    100      -100   <--- change the value here
5    2     SUM     110      110
6    3     Text3   4        4
7    3     SUM     4        4

据我所知,我不知道如何更改这些值。我试过这样:
df[df[0].str.contains('\d%', regex= True, na=False)]

这样,我就拥有了df[0]具有这些要求的值的所有行 - 问题是我不知道如何将它们在Total列中的值更改为负数。我试过了,但它没有帮助并且有错误:

df['Total'] = np.where(df[df[0].str.contains('\d%', regex= True, na=False)], df['Total'] *= -1, df['Total'])

另外,我想将值更改df[0] == SUM 为负值,但前提是与 SUM 同一组中的所有元素都是满足先前要求的值。
例子:

   Group   0       1       Total      
0    1     Text    5        5
1    1     Text2   5        5
2    1     SUM     10       10
3    2     10%     10       -10  
4    2     100%    100      -100 
5    2     SUM     110      -110   <--- here should be a negative value - they are in the same group 
6    3     Text3   4        4
7    3     SUM     4        4

如果在给定组(在本例中为组 2)中存在df[0]仅包含数字和百分比符号的值,则它们的Total列值应为负数。此外,如果组中的所有行都满足此条件(这些是带有百分号的数字),那么列中df[0] == SUM的值Total也应该更改符号。
如何将它连接到这样的正则表达式?如何SUM在给定组中依赖同一组中的先前值?

标签: pythonpandas

解决方案


利用:

#test number with %
m = df[0].str.contains('\d%', regex= True, na=False)

#multiple if matched condition
df.loc[m, 'Total'] *= -1

#test if all values without last are matched m condition    
m1 = m.groupby(df['Group']).transform(lambda x: x[:-1].all())

#multiple last value of group if matched m1 and not matched m
df.loc[m1 & ~m, 'Total'] *= -1
print (df)
   Group      0    1  Total
0      1   Text    5      5
1      1  Text2    5      5
2      1    SUM   10     10
3      2    10%   10    -10
4      2   100%  100   -100
5      2    SUM  110   -110
6      3  Text3    4      4
7      3    SUM    4      4

推荐阅读