基于条件从当前行和前一行的值创建列表

4

我有一个包含两列'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'本身的列表。
最终输出应如下所示:
    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]

解决方案对您有用吗? - Ruthger Righart
是的,下面的解决方案很有效。 - Rajesh
不要忘记给予你的投票或反馈,这有助于社区。 - Ruthger Righart
3个回答

3
使用列表解析,在numpy数组中创建列表,当 b < 0 时,通过由DataFrame.assign添加的移位辅助列s进行操作:Series.shift
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]

3

使用Series.to_numpy将序列转换为numpy数组,并通过添加newaxis来增加维度,然后使用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]

0

加载数据:

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()

将矩阵写入新的数据框列'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']])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接