dataframe上带有IF条件的Python循环给出了不完整的结果或KeyError

2024-05-18 23:27:22 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个数据帧:

d = {'A': [2, 1, 4, 5, 7, 8, 7, 5], 'B': [5, 7, 7, 6, 10, 9, 12, 10]}
testdf = pd.DataFrame(data=d)


    A   B
0   2   5
1   1   7
2   4   7
3   5   6
4   7   10
5   8   9
6   7   3
7   5   2

我正在比较这两列,如果A>;A-1和B<;B-1,否则附加“断开”

array = []

for i in range(1,len(testdf)):
   
    if testdf.A[i] > testdf.A[i-1]:
        
        if testdf.B[i] < testdf.B[i-1]:
        
            array.append('INSIDE')
        
        else:
            
            array.append('BROKEN')

结果是:

['BROKEN', 'INSIDE', 'BROKEN', 'INSIDE']

但我希望:

['BROKEN', 'BROKEN', 'INSIDE', 'BROKEN', 'INSIDE', 'BROKEN', 'BROKEN']

我尝试了循环起点的不同变化

for i in range(len(testdf)-1):

但它只会导致关键错误

如何改进代码以使其按预期运行


Tags: 数据ingtdataframefordatalenif
3条回答

对于基于pandas的方法,可以使用^{}

m = df.diff()
m = (m.A>0)&(m.B<0)
df['new_col'] = np.where(m, 'INSIDE', 'BROKEN')

print(df)
   A   B new_col
0  2   5  BROKEN
1  1   7  BROKEN
2  4   7  BROKEN
3  5   6  INSIDE
4  7  10  BROKEN
5  8   9  INSIDE
6  7   3  BROKEN
7  5   2  BROKEN

给你:

import numpy as np
import pandas as pd

d = {'A': [2, 1, 4, 5, 7, 8, 7, 5], 'B': [5, 7, 7, 6, 10, 9, 12, 10]}
testdf = pd.DataFrame(data=d)

mask1 = testdf.A > testdf.A.shift()
mask2 = testdf.B < testdf.B.shift()

res = np.where(mask1 & mask2, 'INSIDE', 'BROKEN')[1:]
print(res)

输出:

['BROKEN' 'BROKEN' 'INSIDE' 'BROKEN' 'INSIDE' 'BROKEN' 'BROKEN']

对于预期的输出,需要附加else语句:

array = []
for i in range(1,len(testdf)):
    if testdf.A[i] > testdf.A[i-1]:
        if testdf.B[i] < testdf.B[i-1]:
            array.append('INSIDE')
        else:
            array.append('BROKEN')
    else:
        array.append('BROKEN')

非循环解决方案,也有已测试的第一个值,因此与原始值相同的长度,如果需要相同的输出,则通过索引[1:]删除第一个值:

mask = testdf['A'].gt(testdf['A'].shift()) & testdf['B'].lt(testdf['B'].shift())


out = np.where(mask, 'INSIDE', 'BROKEN').tolist()
print (out)
['BROKEN', 'BROKEN', 'BROKEN', 'INSIDE', 'BROKEN', 'INSIDE', 'BROKEN', 'BROKEN']

out1 = np.where(mask, 'INSIDE', 'BROKEN')[1:].tolist()
print (out1)
['BROKEN', 'BROKEN', 'INSIDE', 'BROKEN', 'INSIDE', 'BROKEN', 'BROKEN']

相关问题 更多 >

    热门问题