我有一个dataframe列,其中包含多个不同的文本限定符,并且我希望能够设置一个新列,该列针对每一行检查文本是否在每一行中,是否这样做或是否如此。我正在尝试剥离数据,只返回下面的蔬菜和淀粉,但是由于数据中的关键字种类繁多,我不能只说COL1中的蔬菜是否是col2 =蔬菜。
示例:
df['COL1']
0 PB~Cucumber_IT~_TL~Vegatables_SP~
1 PB~Potato_IT~_TB~Starch_SP~
2 PB~Onion_IT~_PE~Vegatables_BA~
我尝试过:
for i in df['COL1']:
if 'TL~' in df['COL1'][i]:
df['COL2'][i] = df['COL1'][i].str.split('TL~').str[1].str.split('_SP~').str[0]
elif 'TB~' in df['COL1'][i]:
df['COL2'][i] = df['COL1'][i].str.split('TB~').str[1].str.split('_SP~').str[0]
elif 'PE~' in df['COL1'][i]:
df['COL2'][i] = df['COL1'][i].str.split('PE~').str[1].str.split('_BA~').str[0]
预期输出:
df['COL2']
0 Vegatables
1 Starch
2 Vegatables
df.info()输出: *注意-为了适应需要,我删除了一些列,并出于隐私目的将其重命名。 thiscolumn是我要使用的df列:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 54 entries, 0 to 53
Data columns (total 16 columns):
notthiscolumn4 54 non-null object
thiscolumn 54 non-null object
notthiscolumn3 54 non-null object
notthiscolumn2 54 non-null object
notthiscolumn 54 non-null object
dtypes: object(16)
尝试不同的操作时,我遇到了各种各样的错误: -str没有属性str -当它表示它是一个np.object时,我曾尝试使用iterrows,但随后出现索引问题。 -值的长度与索引的长度不匹配。
任何方向都值得赞赏!
答案 0 :(得分:0)
IIUC,在这种情况下,您可以申请np.select
参见doc
import numpy as np
import pandas as pd
from io import StringIO
txt ="""COL1
0 PB~Cucumber_IT~_TL~Vegatables_SP~
1 PB~Potato_IT~_TB~Starch_SP~
2 PB~Onion_IT~_PE~Vegatables_BA~"""
df = pd.read_csv(StringIO(txt),
delim_whitespace=True)
condList = [df["COL1"].str.contains("TL~"),
df["COL1"].str.contains("TB~"),
df["COL1"].str.contains("PE~")]
choiceList = [df["COL1"].str.split('TL~').str[1].str[:-4],
df["COL1"].str.split('TB~').str[1].str[:-4],
df["COL1"].str.split('PE~').str[1].str[:-4]]
df["COL2"] = np.select(condList, choiceList)
您必须确保所有条件都是互斥的。
答案 1 :(得分:0)
无需使用numpy,pandas可以通过多种方式进行此类操作。
import pandas as pd
def parse_row_col1(row):
result = ""
if 'TL~' in row.COL1:
result = row.COL1.split('TL~')[1].split('_SP~')[0]
elif 'TB~' in row.COL1:
result = row.COL1.split('TB~')[1].split('_SP~')[0]
elif 'PE~' in row.COL1:
result = row.COL1.split('PE~')[1].split('_BA~')[0]
return result
parse_res = pd.Series((parse_row_col1(curr) for curr in df.itertuples(index=False)))
这种在行元组上迭代的方法并不比使用numpy的select
快,但是在处理大量条件时应该简单得多。不仅如此,而且正如@rpanai在其答案中指出的那样,select
仅能处理互斥条件,而上述解决方案无论如何都起作用。