我想复制类似于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")
答案 0 :(得分:3)
使用shift
构建一个布局数组,其中应显示'Y'
值,然后使用numpy.where
创建列:
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')
如果您的DataFrame中有多个列,则您需要使用csv_in['Country'].shift()
而不是上述代码中的较短表示法。
一些略微扩展的样本数据的结果输出:
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
访问器将字符串函数应用于列,如文档的Working with Text Data部分所述。
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
值。如果你真的想按照重要性的顺序编写条件,你可以在x_cond & (csv_in['Result'] == 'N')
内做loc
之类的事情,尽管它可能会影响性能。
更新了输出:
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