基于当前行上方或下方第n行的条件-Python

基于当前行上方或下方第n行的条件-Python,python,pandas,Python,Pandas,我想复制一些类似于Alteryx中的“多行公式”工具的东西。我目前正在读取一个csv文件,如果同一测试列中另一行的值为真,我希望能够在列表中设置一个值 样本数据 **Country** China India Brazil Indonesia 当它在包含巴西的行中循环时,应将“Y”添加到新列表中,因为中国在上面两行。其余部分应加上“N” import pandas as pd csv_in = pd.read_csv('C:/sample.csv') kind = []

我想复制一些类似于Alteryx中的“多行公式”工具的东西。我目前正在读取一个csv文件,如果同一测试列中另一行的值为真,我希望能够在列表中设置一个值

样本数据

**Country**
China
India
Brazil
Indonesia
当它在包含巴西的行中循环时,应将“Y”添加到新列表中,因为中国在上面两行。其余部分应加上“N”

import pandas as pd

csv_in = pd.read_csv('C:/sample.csv')

kind = []                           

for row in csv_in['Country']:
    if ***two rows above this row*** == 'China':
        kind.append('Y')
    elif ***one row below this row*** == 'Canada':
        kind.append('Y')
    else:
        kind.append("N")

csv_in['Result'] = kind
我很难找到任何与这个问题相关的东西。任何帮助都将不胜感激

编辑:我意识到除了最初的要求之外,我还需要做一些事情

  for row in csv_in['Country']:
      if  'hina' in ***two rows above this row***:
          kind.append('Y')
      elif ***one row below this row***.startswith('Can'):
          kind.append('X')
      else:
          kind.append("N")
用于构建布尔数组,其中应显示
'Y'
值,然后用于创建列:

import numpy as np

y_cond = (csv_in.shift(2) == 'China') | (csv_in.shift(-1) == 'Canada')
csv_in['Result'] = np.where(y_cond, 'Y', 'N')
如果数据框中有多个列,则需要在['Country'].shift()中使用
csv_,而不是上面代码中的较短符号

一些稍微扩展的样本数据的结果输出:

     Country Result
0      China      N
1      India      N
2     Brazil      Y
3  Indonesia      N
4     Bhutan      N
5     Mexico      Y
6     Canada      N
7       Peru      N
8   Honduras      N
编辑:

如果你想分配非二进制值,我会采取稍微不同的方法

首先将结果初始化为
'N'
。对于每个条件,与前面类似地创建一个布尔数组,并使用
loc
指定所需的值。按与重要性相反的顺序执行此操作,因为后续匹配将覆盖以前的匹配

请注意,您可以使用
.str
访问器将字符串函数应用于列,如文档部分所述

csv_in['Result'] = 'N'

x_cond = csv_in['Country'].shift(-1).str.startswith('Can').fillna(False)
csv_in.loc[x_cond, 'Result'] = 'X'

y_cond = csv_in['Country'].shift(2).str.contains('hina').fillna(False)
csv_in.loc[y_cond, 'Result'] = 'Y'
.fillna(False)
是必需的,因为
loc
需要纯布尔值,
shift
引入
NaN
值。如果您确实想按重要性顺序编写条件,可以在
loc
内部执行类似于
x_cond&(csv_in['Result']='N')
的操作,尽管这可能会影响性能

更新输出:

     Country Result
0      China      N
1      India      N
2     Brazil      Y
3  Indonesia      N
4     Bhutan      N
5     Mexico      X
6     Canada      N
7       Peru      N
8   Honduras      N

在可索引结构(如pandas dataframe)上迭代,然后在两种特殊情况下使用偏移量作为条件,构建长度相同的布尔序列,并在两个“列表”中的位置之间隐式地进行1对1映射,这看起来有些笨拙。根据数据帧“国家”列长度,一次编制Falsy或“N”列表,并找到数据帧的特殊情况索引,然后将下面2行和上面1行的偏移量分别设置为True或“y”。。。现在@root已经给出了答案;-)谢谢这正是我要求的!但我是个白痴,如果我想让加拿大返回“X”怎么办。如果我想使用startswith()或“in”,该怎么办。我收到此错误:“series对象没有属性startswith”。我更新了笨拙的代码。对不起!