我想复制类似于 Alteryx 中的“多行公式”工具的东西。我当前正在读取 csv 文件,并且希望能够在同一测试列中另一行的值为 true 时在列表中设置一个值。
示例数据
**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")
最佳答案
使用shift
要构建 'Y'
值应出现的 bool 数组,然后使用 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'
。对于每个条件,与以前类似地创建一个 bool 数组,并使用 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
需要纯 bool 值,而 shift
引入了 NaN
值(value)观。如果您确实想按重要性顺序编写条件,您可以在 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
关于python - 基于当前行上方或下方第 n 行的条件 - Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37686449/