免责声明:这可能是重复的,但我找不到确切的解决方案。请随时将此问题标记为重复问题,并在评论中提供重复问题的链接。
我仍在学习python数据帧操作,这可能有一个非常简单的解决方案,但我无法理解。
我有一个带有单列的python数据帧。现在,如果满足某些条件,我想将每行的值更改为前一行的值。我已经创建了一个循环解决方案来实现这一点,但我希望有一个更有效的解决方案。
创建初始数据:
import numpy as np
import pandas as pd
data = np.random.randint(5,30,size=20)
df = pd.DataFrame(data, columns=['random_numbers'])
print(df)
random_numbers
0 6
1 24
2 29
3 18
4 22
5 17
6 12
7 7
8 6
9 27
10 29
11 13
12 23
13 6
14 25
15 24
16 16
17 15
18 25
19 19
现在假设两个条件是1(值小于10和2(值大于20。在任何一种情况下,请将行值设置为前一行值。这已经在循环格式中实现如下:
for index,row in df.iterrows():
if index == 0:
continue;
if(row.random_numbers<10):
df.loc[index,'random_numbers']=df.loc[index-1,'random_numbers']
if(row.random_numbers>20):
df.loc[index,'random_numbers']=df.loc[index-1,'random_numbers']
random_numbers
0 6
1 6
2 6
3 18
4 18
5 17
6 12
7 12
8 12
9 12
10 12
11 13
12 13
13 13
14 13
15 13
16 16
17 15
18 15
19 19
请建议一种更有效的方法来实现这个逻辑,因为我正在使用大量的行。
您可以用NaN
替换小于10和大于20的值,然后使用panda。DataFrame.fill((,用前一行的值填充nan。
mask = (df['random_numbers'] < 10) | (df['random_numbers'] > 20)
# Since you escape with `if index == 0:`
mask[df.index[0]] = False
df.loc[mask, 'random_numbers'] = np.nan
df['random_numbers'].ffill(inplace=True)
# Original
random_numbers
0 7
1 28
2 8
3 14
4 12
5 20
6 21
7 11
8 16
9 27
10 19
11 23
12 18
13 5
14 6
15 11
16 6
17 8
18 17
19 8
# After replaced
random_numbers
0 7.0
1 7.0
2 7.0
3 14.0
4 12.0
5 20.0
6 20.0
7 11.0
8 16.0
9 16.0
10 19.0
11 19.0
12 18.0
13 18.0
14 18.0
15 11.0
16 11.0
17 11.0
18 17.0
19 17.0
我们也可以用一种更简单的方法来实现,将.mask()
与.ffill()
一起使用,并对[1:]
进行切片,如下所示:
df['random_numbers'][1:] = df['random_numbers'][1:].mask((df['random_numbers'] < 10) | (df['random_numbers'] > 20))
df['random_numbers'] = df['random_numbers'].ffill(downcast='infer')
.mask()
测试条件,并在条件为true时用NaN
替换(如果未提供参数other=
,则默认为用NaN
替换(。保留不满足条件的行的原始值。
注意,通过在对.ffill()
的调用中提供downcast='infer'
,结果数字被保持为integer
,而不是意外地将转换为float
类型。
我们在第一行使用[1:]
来确保行0
上的数据在没有转换的情况下不受影响。
# Original data: (reusing your sample data)
random_numbers
0 6
1 24
2 29
3 18
4 22
5 17
6 12
7 7
8 6
9 27
10 29
11 13
12 23
13 6
14 25
15 24
16 16
17 15
18 25
19 19
# After transposition:
random_numbers
0 6
1 6
2 6
3 18
4 18
5 17
6 12
7 12
8 12
9 12
10 12
11 13
12 13
13 13
14 13
15 13
16 16
17 15
18 15
19 19