Pandas - 根据条件生成列

问题描述

这是示例数据集:

>>> df
   vn    pt    st nst stb mid
0   a   0.1     a   b   0   3
1   a   0.2     a   b   4   3
2   a   0.3     a   b   1   3
3   a   0.3     b   a   1   3
4   a   0.4     a   b   1   3
5   a   0.4     a   b   2   3
6   a   0.5     c   b   6   3
7   a   0.5     c   b   0   3
8   a   0.6     c   b   1   3
9   a   1.1     b   c   2   3
10  a   1.2     b   c   1   3
11  a   1.3     d   b   6   3
12  a   1.4     d   b   0   3
13  a   1.4     d   b   1   3
14  a   1.5     e   d   2   3
15  a   1.6     d   e   0   3
16  a   0.1     d   y   1   7
17  a   0.2     y   d   4   7
18  a   0.3     y   d   1   7
19  a   0.4     y   x   3   7
20  a   0.5     x   z   0   7
21  a   0.6     p   z   2   7
22  a   0.6     z   p   6   7
23  a   1.1     p   q   3   7

从这个数据集中,我想创建两个新列 srnsr。需要记住的几点:stb 值表示 st 的对应值。当认情况下 stnst注册了新字符串时,sr=0 相应地nsr=0

st代码:1.当st的值连续相同sr=sr+stb时,2.当nst的值移动到st时{{1 }},3.当有一个新值分配给sr=nsr+stb时,st

st=stb代码:1.当 nst 的值连续相同时,nst 将保持不变(不变),2.当 nsr 的值移动到 {前一个st的{​​1}}值应该返回到下一个nst,3.当有一个新的值分配给sr时,nsr

迭代一直持续到nst连续的同一个值(当出现不同的mid时,会从头开始迭代)。要生成这两列,请查看以下示例:

nsr=0

预期输出

mid

解决方法

这是迄今为止的部分解决方案,基于评论中的问题和讨论:

sr 列已经得到了预期的结果,但 nsr 还需要一些进一步的工作:

df['sr'] = df.groupby(['mid','st'])['stb'].cumsum()

结果:

print(df)

   vn   pt st nst  stb  mid  sr
0   a  0.1  a   b    0    3   0
1   a  0.2  a   b    4    3   4
2   a  0.3  a   b    1    3   5
3   a  0.3  b   a    1    3   1
4   a  0.4  a   b    1    3   6
5   a  0.4  a   b    2    3   8
6   a  0.5  c   b    6    3   6
7   a  0.5  c   b    0    3   6
8   a  0.6  c   b    1    3   7
9   a  1.1  b   c    2    3   3
10  a  1.2  b   c    1    3   4
11  a  1.3  d   b    6    3   6
12  a  1.4  d   b    0    3   6
13  a  1.4  d   b    1    3   7
14  a  1.5  e   d    2    3   2
15  a  1.6  d   e    0    3   7
16  a  0.1  d   y    1    7   1
17  a  0.2  y   d    4    7   4
18  a  0.3  y   d    1    7   5
19  a  0.4  y   x    3    7   8
20  a  0.5  x   z    0    7   0
21  a  0.6  p   z    2    7   2
22  a  0.6  z   p    6    7   6
23  a  1.1  p   q    3    7   5

nsr 的部分工作:

m1 = df['st'].ne(df['st'].groupby(df['mid']).shift())
m2 = df['st'].eq(df['nst'].shift())
m3 = df['nst'].eq(df['st'].shift())
m = m1 & (m2 | m3)

df['nsr'] = np.where(m,df['sr'].shift(),np.nan)

m11 = df['mid'] != df['mid'].shift()
df['nsr'] = np.where(m11,df['nsr'])

df['nsr'] = df['nsr'].ffill(downcast='infer')

结果:

print(df)

   vn   pt st nst  stb  mid  sr  nsr
0   a  0.1  a   b    0    3   0    0
1   a  0.2  a   b    4    3   4    0
2   a  0.3  a   b    1    3   5    0
3   a  0.3  b   a    1    3   1    5
4   a  0.4  a   b    1    3   6    1
5   a  0.4  a   b    2    3   8    1
6   a  0.5  c   b    6    3   6    1
7   a  0.5  c   b    0    3   6    1
8   a  0.6  c   b    1    3   7    1
9   a  1.1  b   c    2    3   3    7
10  a  1.2  b   c    1    3   4    7
11  a  1.3  d   b    6    3   6    4
12  a  1.4  d   b    0    3   6    4
13  a  1.4  d   b    1    3   7    4
14  a  1.5  e   d    2    3   2    7
15  a  1.6  d   e    0    3   7    2
16  a  0.1  d   y    1    7   1    0
17  a  0.2  y   d    4    7   4    1
18  a  0.3  y   d    1    7   5    1
19  a  0.4  y   x    3    7   8    1
20  a  0.5  x   z    0    7   0    8
21  a  0.6  p   z    2    7   2    8
22  a  0.6  z   p    6    7   6    2
23  a  1.1  p   q    3    7   5    6
,

(部分尝试等待反馈 - 不适合评论。)

根据您的解释,sr 是每个 stbst 对的 nst 的不同累积和。但是,这与您的预期输出不太相符:

>>> df['sr'] = df.groupby(['nst','st'])['stb'].cumsum()
>>> df[['sr']].join([expected['sr'].rename('expected'),(df['sr'] - expected['sr']).rename('diff')])
    sr  expected  diff
0    0         0     0
1    4         4     0
2    5         5     0
3    1         1     0
4    6         6     0
5    8         8     0
6    6         6     0
7    6         6     0
8    7         7     0
9    2         3    -1
10   3         4    -1
11   6         6     0
12   6         6     0
13   7         7     0
14   2         2     0
15   0         7    -7
16   1         1     0
17   4         4     0
18   5         5     0
19   3         8    -5
20   0         0     0
21   2         2     0
22   6         6     0
23   3         5    -2

第 9、10、15、19 和 23 行会发生什么?

例如第 9 行是第一个 b,c,如果我将它与第 3 行进行比较,第一个 b,a 应该是 0+3,第 3 行是 {{1} }.

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...