![](/img/trans.png)
[英]how to subtract previous row value from current row value based on condition in pandas DataFrame?
[英]Create list from value in current row and previous row based on condition
我有一个 dataframe 有两列'a'和'b',其中'b'是'a'的值和前一个值'a'之间的差异
df = pd.DataFrame({'a': [10, 60, 30, 80, 10]})
df['b'] = df['a']-df['a'].shift(1)
a b
0 10 NaN
1 60 50.0
2 30 -30.0
3 80 50.0
4 10 -70.0
我想创建一个新列“c”,其值作为“a”的先前值和“a”的当前值(例如,[60,30])的列表,仅在“b”列为负的情况下。 否则,它必须是当前值“a”本身的列表。
生成的 output 应该看起来像
a b c
0 10 NaN [10]
1 60 50.0 [60]
2 30 -30.0 [60, 30]
3 80 50.0 [80]
4 10 -70.0 [80, 10]
如果 numpy 数组中的b < 0
使用列表推导创建列表,其中由Series.shift
添加的DataFrame.assign
移位辅助列s
:
arr = df.assign(s = df['a'].shift(fill_value=0))[['a','b','s']].to_numpy()
df['c'] = [[s,a] if b < 0 else [a] for a,b,s in arr]
print (df)
a b c
0 10 NaN [10.0]
1 60 50.0 [60.0]
2 30 -30.0 [60.0, 30.0]
3 80 50.0 [80.0]
4 10 -70.0 [80.0, 10.0]
或者与由列表压缩创建的一个元素列表一起使用Series.mask
:
s = pd.Series([[x] for x in df['a']], index=df.index)
#alternative
s = df['a'].apply(lambda x: [x])
df['c'] = s.mask(df['b'].lt(0), s.shift() + s)
print (df)
a b c
0 10 NaN [10]
1 60 50.0 [60]
2 30 -30.0 [60, 30]
3 80 50.0 [80]
4 10 -70.0 [80, 10]
使用Series.to_numpy
并通过添加 newaxis 来增加维度,然后使用 boolean 索引与Series.lt
并分配新值:
df['c'] = df['a'].to_numpy()[:, None].tolist()
df.loc[df['b'].lt(0), 'c'] = df['c'].shift() + df['c']
结果:
a b c
0 10 NaN [10]
1 60 50.0 [60]
2 30 -30.0 [60, 30]
3 80 50.0 [80]
4 10 -70.0 [80, 10]
加载数据:
df = pd.DataFrame({'a': [10, 60, 30, 80, 10]})
df['b'] = df['a']-df['a'].shift(1)
创建一个临时的 Numpy 矩阵:
npa = np.array([df['a'].shift(1), df['a']]).transpose()
将矩阵写入新的 df 列“c”:
df['c'] = list(npa)
如果“b”列中的值大于 0 或 NAN,则将“a”中的值复制到“c”:
df.loc[(df['b'] > 0) | (df['b'].isnull() == True) , 'c'] = pd.Series([[x] for x in df['a']])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.